问题
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