具有内存数据 dotnet 的 ZipArchive

ZipArchive with in memory data dotnet

提问人:Dblock247 提问时间:11/10/2023 更新时间:11/10/2023 访问量:68

问:

我正在尝试使用在内存中创建的数据在 C# 中创建一个 Zip 存档。但是,每次我尝试最终将存档保存到磁盘时,它都是空的。现在我正在使用一个文件进行测试,但它最终将成为一个将被存档的文件列表。

var data = new Data
{
    FirstName = "FirstName",
    LastName = "LastName"
};

var json = JsonConvert.SerializeObject(data, Formatting.Indented);
var bytes = Encoding.UTF8.GetBytes(json);
using var file = new MemoryStream(bytes);

using var archiveStream = new MemoryStream();
var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true);

var archiveEntry = archive.CreateEntry("data.json", CompressionLevel.Fastest);
using var entryStream = archiveEntry.Open();
file.CopyTo(entryStream);

using var fileStream = new FileStream("/Path/To/File/test.zip", FileMode.Create, FileAccess.Write);
archiveStream.CopyTo(fileStream);

我错过了什么?

C# .NET ZipArchive

评论

0赞 JonasH 11/10/2023
如果你想提高效率,你应该:1)直接序列化到entryStream,大多数序列化库都有处理流的方法。2) 使用 fileStream 创建 zip-archive。这两个内存流都不会添加任何内容,除非由于某种原因需要将数据作为字节数组,而您没有显示。
0赞 Dblock247 11/10/2023
感谢您提供的信息@JonasH这只是在控制台应用程序中进行测试。数据将位于 API 调用中,并在响应中返回。不会有要写入的实际磁盘。我只是为测试目的而写的。
0赞 Dblock247 11/10/2023
@JonasH不确定是否可以直接写入条目流。如果你有的话,我很想看看你的例子。
0赞 Dblock247 11/11/2023
确实如此,但这就是我已经在做的事情。我以为您在转换为 json 时建议直接将其转换为入口流。
0赞 JonasH 11/13/2023
是的,这正是我的建议。请参阅我可以将 json 序列化为流

答:

1赞 beautifulcoder 11/10/2023 #1

写入内存流后,您将需要返回到内存流的开头。

archiveStream.Seek(0, SeekOrigin.Begin);
archiveStream.CopyTo(fileStream);
2赞 Schamal 11/10/2023 #2

https://stackoverflow.com/a/17939367/14918126 所述,问题在于需要先处理掉它,然后才能使用它。 在将 它复制到 fileStream 之前,您应该将 的位置设置为开始。 以下解决方案应该有效:archiveStreamarchiveStream

        var data = new Data
        {
            FirstName = "FirstName",
            LastName = "LastName"
        };

        var json = JsonConvert.SerializeObject(data, Formatting.Indented);
        var bytes = Encoding.UTF8.GetBytes(json);
        using var file = new MemoryStream(bytes);

        using var archiveStream = new MemoryStream();
        var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true);

        var archiveEntry = archive.CreateEntry("data.json", CompressionLevel.Fastest);
        using var entryStream = archiveEntry.Open();
        file.CopyTo(entryStream);
        archive.Dispose();

        using var fileStream = new FileStream("./test2.zip", FileMode.Create, FileAccess.Write);
        archiveStream.Seek(0, SeekOrigin.Begin);
        archiveStream.CopyTo(fileStream);

评论

0赞 Dblock247 11/10/2023
感谢您的回复。我确实看到了那篇帖子,但大多数答案都没有显示处置。我一定错过了。道歉。