在内存中从List<Byte[]>创建Zip文件

3
我有一个 Web 服务,返回文件列表。类似这样:
public FileModel(){
  string FileName {get;set;}
  byte[] FileStream {get;set;}
  string FileType {get;set;} 
}

我的服务会返回:
  List<FileModel> files;

我需要将这个列表返回给浏览器,所以我需要将这些文件压缩成一个zip文件夹。然而,我不知道如何做到这一点,因为.NET ZipArchive CreateFromDirectory 要求我提供要压缩的文件所在的目录。但是我没有一个目录,我只有这个列表。我该如何把这个列表转换成一个压缩的文件夹呢?

2
什么是“zip方法”?ZipArchive类的所有构造函数都接受Stream参数。 - Ivan Stoev
我必须将此列表返回给浏览器,但你可以将文件名、文件类型和文件大小返回给浏览器。当用户实际请求特定文件时,你可以返回压缩后的文件。 - Eser
@Eser,不,我实际上需要将文件的压缩文件夹返回给浏览器/用户。 - Mark
1
Iconic的DotNetZip(免费软件)允许您传递一个byte[]来创建zip文件。但我不知道是否有任何东西可以让您传递List<byte()>。 - Kevin
它还允许您将流或byte[]传递给方法,以创建zip文件中的文件。查看您的库的CreateEntry方法是否有一个接受流的重载版本,如果有,请从byte[]创建一个MemoryStream,并将其传递给流。 - Kevin
显示剩余2条评论
1个回答

4

假设

public FileModel(){
    string FileName {get;set;}
    byte[] FileStream {get;set;}
    string FileType {get;set;} 
}

以下内容是用于创建zip文件的:
static class FileModelCompression {

    public static Stream Compress(this IEnumerable<FileModel> files) {
        if (files.Any()) {
            var ms = new MemoryStream();
            using(var archive = new ZipArchive(ms, ZipArchiveMode.Create, leaveOpen: true)) {
                foreach (var file in files) {
                    var entry = archive.add(file);
                }
            }// disposal of archive will force data to be written to memory stream.
            ms.Position = 0; //reset memory stream position.
            return ms;
        }
        return null;
    }

    private static ZipArchiveEntry add(this ZipArchive archive, FileModel file) {
        var entry = archive.CreateEntry(file.FileName, CompressionLevel.Fastest);
        using (var stream = entry.Open()) {
            file.FileStream.CopyTo(stream);
        }
        return entry;
    }
}

如果我们使用您的代码,我们可以创建此文件并查看zip中的文件,但是: 当我们尝试提取zip时,会出现错误,指示存档意外结束。 - ProblemAnswerQue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接