我的问题与此问题有点相似,但它与ASP.NET有关,我的要求略有不同:Android将文件附加到zip文件,而不必重写整个zip文件?
我需要将数据插入到用户下载的zip文件中(最多不需要1KB的数据,实际上这是Adword离线转换的数据)。zip文件是通过ASP.NET网站下载的。因为zip文件已经足够大(10 MB),可以避免服务器过载,所以我需要在不重新压缩所有内容的情况下插入这些数据。我能想出两种方法来做这件事。
-
方法A:找到一种zip技术,可以在zip文件中嵌入特定文件,该特定文件是未压缩嵌入的。假设没有校验和,那么就可以很容易地用zip文件本身中的特定数据覆盖这个未压缩文件的比特。如果可能的话,这必须得到所有解压缩工具的支持(Windows集成zip、winrar、7zip…)
-
方法B:将一个额外的文件附加到原始ZIP文件,而无需重新压缩!这个额外的文件必须存储在ZIP文件中的嵌入式文件夹中。
我看了一下SevenZipSharp,它有一个值为Create
和Append
的枚举SevenZip.CompressionMode
,这让我认为可以实现方式B。根据常见问题解答,DotNetZip似乎也能很好地与Stream配合使用。
但是如果方式A是可能的,我更喜欢它,因为服务器端不需要额外的zip库!
好吧,多亏了DotNetZip,我能够以一种非常节省资源的方式做我想做的事情:
using System.IO;
using Ionic.Zip;
class Program {
static void Main(string[] args) {
byte[] buffer;
using (var memoryStream = new MemoryStream()) {
using (var zip = new ZipFile(@"C:tempMylargeZipFile.zip")) {
// The file on which to override content in MylargeZipFile.zip
// has the path "PathFileToUpdate.txt"
zip.UpdateEntry(@"PathFileToUpdate.txt", @"Hello My New Content");
zip.Save(memoryStream);
}
buffer = memoryStream.ToArray();
}
// Here the buffer will be sent to httpResponse
// httpResponse.Clear();
// httpResponse.AddHeader("Content-Disposition", "attachment; filename=MylargeZipFile.zip");
// httpResponse.ContentType = "application/octe-t-stream";
// httpResponse.BinaryWrite(buffer);
// httpResponse.BufferOutput = true;
// Just to check it worked!
File.WriteAllBytes(@"C:tempResult.zip", buffer);
}
}