我们有一个用户可以下载媒体的页面,我们构建一个类似于以下的文件夹结构并将其压缩并在响应中将其发送回用户。
ZippedFolder.zip
- Folder A
- File 1
- File 2
- Folder B
- File 3
- File 4
完成此操作的现有实现将文件和目录临时保存到文件系统,然后在最后删除它们。我们试图摆脱这样做,并希望完全记忆中完成这一点。
我能够成功创建包含文件的ZipFile,但我遇到的问题是创建文件夹A 和文件夹B 并向这些文件添加文件然后将这两个文件夹添加到Zip文件中。
如何在不保存到文件系统的情况下执行此操作?
将文件流保存到zip文件然后在响应上设置输出流的代码如下:
public Stream CompressStreams(IList<Stream> Streams, IList<string> StreamNames, Stream OutputStream = null)
{
MemoryStream Response = null;
using (ZipFile ZippedFile = new ZipFile())
{
for (int i = 0, length = Streams.Count; i < length; i++)
{
ZippedFile.AddEntry(StreamNames[i], Streams[i]);
}
if (OutputStream != null)
{
ZippedFile.Save(OutputStream);
}
else
{
Response = new MemoryStream();
ZippedFile.Save(Response);
// Move the stream back to the beginning for reading
Response.Seek(0, SeekOrigin.Begin);
}
}
return Response;
}
编辑我们正在使用DotNetZip进行压缩/解压缩库。
答案 0 :(得分:0)
这是使用System.IO.Compression.ZipArchive
执行此操作的另一种方法public Stream CompressStreams(IList<Stream> Streams, IList<string> StreamNames, Stream OutputStream = null)
{
MemoryStream Response = new MemoryStream();
using (ZipArchive ZippedFile = new ZipArchive(Response, ZipArchiveMode.Create, true))
{
for (int i = 0, length = Streams.Count; i < length; i++)
using (var entry = ZippedFile.CreateEntry(StreamNames[i]).Open())
{
Streams[i].CopyTo(entry);
}
}
if (OutputStream != null)
{
Response.Seek(0, SeekOrigin.Begin);
Response.CopyTo(OutputStream);
}
return Response;
}
并进行一点测试:
using (var write = new FileStream(@"C:\users\Public\Desktop\Testzip.zip", FileMode.OpenOrCreate, FileAccess.Write))
using (var read = new FileStream(@"C:\windows\System32\drivers\etc\hosts", FileMode.Open, FileAccess.Read))
{
CompressStreams(new List<Stream>() { read }, new List<string>() { @"A\One.txt" }, write);
}
re:你的评论 - 抱歉,不确定它是否在后台创建了一些内容,但你不是自己创建它来做任何事情