Overwrite contents of ZipArchiveEntry

二次信任 提交于 2020-07-05 09:17:05

问题


How can I overwrite contents of a ZipArchiveEntry? Following code using StreamWriter with StringBuilder fails if the new file contents are shorter than the original ones, for example:

using System.IO.Compression;
//...
using (var archive = ZipFile.Open("Test.zip", ZipArchiveMode.Update))
{
   StringBuilder document;
   var entry = archive.GetEntry("foo.txt");//entry contents "foobar123"
   using (StreamReader reader = new StreamReader(entry.Open()))
   {
      document = new StringBuilder(reader.ReadToEnd());
   }

   document.Replace("foobar", "baz"); //builder contents "baz123"

   using (StreamWriter writer = new StreamWriter(entry.Open()))
   {
      writer.Write(document); //entry contents "baz123123", expected "baz123"
   }
}

Produces file containing new and old contents mixed up "baz123123" instead of expected "baz123". Is there perhaps a way how to discard the old contents of ZipArchiveEntry before writing the new ones?
note: I do not want to extract the file, I would like to change contents of the archive.


回答1:


Updating the archive means you are either adding, moving or removing an entry from the archive.

Consider doing the following steps.

  • Get the entry content

  • Remove the entry from the archive (take note of name/location)

  • Modify content as desired.

  • Add modified content back to the archive.




回答2:


An alternative is to SetLength(document.Length) of the entry.Open() stream.

using(var stream = entry.Open())
{
   stream.SetLength(document.Length);
   using (StreamWriter writer = new StreamWriter(stream))
   {
      writer.Write(document); //entry contents "baz123"
   }
}



回答3:


The below code maintains your basic code structure, but explicitly deletes and recreates the file to ensure that 'leftover' data does not remain.

using (var archive = ZipFile.Open("Test.zip", ZipArchiveMode.Update))
{
    StringBuilder document;
    var entry = archive.GetEntry("foo.txt");//entry contents "foobar123"
    using (StreamReader reader = new StreamReader(entry.Open()))
    {
       document = new StringBuilder(reader.ReadToEnd());
    }

    entry.Delete();
    entry = archive.CreateEntry("foo.txt");
    document.Replace("foobar", "baz"); //builder contents "baz123"

    using (StreamWriter writer = new StreamWriter(entry.Open()))
    {
       writer.Write(document);
    }
}


来源:https://stackoverflow.com/questions/46810169/overwrite-contents-of-ziparchiveentry

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!