将多个文件存入内存流的Ziparchive
问题描述:
我已经研究了类似问题的答案,但还没有看到将多个文件收集到一个ziparchive以供传输下载的答案。以下给出没有错误,但不返回一个可识别的zip文件。将多个文件存入内存流的Ziparchive
public async Task<HttpResponseMessage> SendAZipOfFiles()
{
var memoryStream = new MemoryStream();
var response = new HttpResponseMessage(HttpStatusCode.OK);
List<string> filepaths = await GetSomeFiles();
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (string filepath in filepaths)
{
string filename = Path.GetFileName(filepath);
using (StreamReader reader = new StreamReader(filepath))
using (StreamWriter writer = new StreamWriter(archive.CreateEntry(filename).Open()))
{
writer.Write(reader.ReadToEnd());
}
}
}
memoryStream.Position = 0;
response.Content = new StreamContent(memoryStream);
response.Content.Headers.ContentLength = memoryStream.Length;
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "TheFile.zip")
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
return response;
}
答
我看你使用StreamReader
和StreamWriter
,这不仅是无用你的目的,而是因为他们是专门用来读取和写入文本文件可能产生的编码问题。
如果您需要添加到您的档案中的任何类型的文件,而不仅仅是纯文本文件,他们可能会在读/写时破坏数据。
相反,只需复制原始流归档条目:
public async Task<HttpResponseMessage> SendAZipOfFiles()
{
var memoryStream = new MemoryStream();
var response = new HttpResponseMessage(HttpStatusCode.OK);
List<string> filepaths = await GetSomeFiles();
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (string filepath in filepaths)
{
string filename = Path.GetFileName(filepath);
var entry = archive.CreateEntry(filename);
using (var file = File.OpenRead(filename))
using (var entryStream = entry.Open())
{
await file.CopyToAsync(entryStream);
}
}
}
memoryStream.Position = 0;
response.Content = new StreamContent(memoryStream);
response.Content.Headers.ContentLength = memoryStream.Length;
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "TheFile.zip")
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
return response;
}
答
原来,我的问题是在打字稿侧。
我确实改变了代码,替换:
string filename = Path.GetFileName(filepath);
using (StreamReader reader = new StreamReader(filepath))
using (StreamWriter writer = new
StreamWriter(archive.CreateEntry(filename).Open()))
{
writer.Write(reader.ReadToEnd());
}
与简单:
archive.CreateEntryFromFile(filepath, Path.GetFileName(filepath));
侧面说明,但是当你打出来的荏苒部分作为单独的方法变得更容易了很多(单元测试。 –