gpt4 book ai didi

C# ZipArchive - 如何在不写入磁盘的情况下嵌套内部 .zip 文件

转载 作者:行者123 更新时间:2023-11-30 15:14:10 24 4
gpt4 key购买 nike

我需要在内存中创建一个压缩文件,然后将压缩文件发送给客户端。但是,在某些情况下,创建的 zip 文件需要包含也在内存中生成的其他 zip 文件。例如,文件结构可能如下所示:

 SendToClient.zip
InnerZip1.zip
File1.xml
File2.xml
InnerZip2.zip
File3.xml
File4.xml

我一直在尝试使用 System.IO.Compression.ZipArchive 库。我无法使用 System.IO.Compression.ZipFile 库,因为我项目的 .NET 版本与其不兼容。

这是我尝试过的示例。

public Stream GetMemoryStream() {
var memoryStream = new MemoryStream();
string fileContents = "Lorem ipsum dolor sit amet";
string entryName = "Lorem.txt";
string innerZipName = "InnerZip.zip";
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) {
ZipArchiveEntry entry = archive.CreateEntry(Path.Combine(innerZipName, entryName), CompressionLevel.Optimal);
using (var writer = new StreamWriter(entry.Open())) {
writer.Write(fileContents);
}
}
return memoryStream
}

但是,这只是将 Lorem.txt 放在名为“Inner.zip”的文件夹中(而不是实际的 zip 文件中)。

如果我创建一个名为“Inner.zip”的条目而不写入它,我可以创建一个空的内部 zip 文件。不过,我无法向其中添加任何内容,之后写入名为“Inner.zip\Lorem.txt”的条目只会再次创建一个文件夹(以及同名的空 .zip 文件)。

我也试过创建一个单独的存档,用内存流序列化它,然后将其作为 .zip 写入原始存档。

public Stream CreateOuterZip() {
var memoryStream = new MemoryStream();
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) {
ZipArchiveEntry entry = archive.CreateEntry("Outer.zip", CompressionLevel.NoCompression);
using (var writer = new BinaryWriter(entry.Open())) {
writer.Write(GetMemoryStream().ToArray());
}
}
return memoryStream;
}

这只会创建一个 Windows 不知道如何打开的无效 .zip 文件。

提前致谢!

最佳答案

所以我创建了一个 FileStream 而不是 MemoryStream,这样可以更轻松地测试代码

public static Stream CreateOuterZip()
{
string fileContents = "Lorem ipsum dolor sit amet";

// Final zip file
var fs = new FileStream(
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SendToClient.zip"), FileMode.OpenOrCreate);

// Create inner zip 1
var innerZip1 = new MemoryStream();
using (var archive = new ZipArchive(innerZip1, ZipArchiveMode.Create, true))
{
var file1 = archive.CreateEntry("File1.xml");
using (var writer = new BinaryWriter(file1.Open()))
{
writer.Write(fileContents); // Change fileContents to real XML content
}
var file2 = archive.CreateEntry("File2.xml");
using (var writer = new BinaryWriter(file2.Open()))
{
writer.Write(fileContents); // Change fileContents to real XML content
}
}

// Create inner zip 2
var innerZip2 = new MemoryStream();
using (var archive = new ZipArchive(innerZip2, ZipArchiveMode.Create, true))
{
var file3 = archive.CreateEntry("File3.xml");
using (var writer = new BinaryWriter(file3.Open()))
{
writer.Write(fileContents); // Change fileContents to real XML content
}
var file4 = archive.CreateEntry("File4.xml");
using (var writer = new BinaryWriter(file4.Open()))
{
writer.Write(fileContents); // Change fileContents to real XML content
}
}

using (var archive = new ZipArchive(fs, ZipArchiveMode.Create, true))
{
// Create inner zip 1
var innerZipEntry = archive.CreateEntry("InnerZip1.zip");
innerZip1.Position = 0;
using (var s = innerZipEntry.Open())
{
innerZip1.WriteTo(s);
}

// Create inner zip 2
var innerZipEntry2 = archive.CreateEntry("InnerZip2.zip");
innerZip2.Position = 0;
using (var s = innerZipEntry2.Open())
{
innerZip2.WriteTo(s);
}
}

fs.Close();
return fs; // The file is written, can probably just close this
}

您显然可以修改此方法以返回 MemoryStream,或将方法更改为 Void 以仅将 zip 文件写入磁盘

关于C# ZipArchive - 如何在不写入磁盘的情况下嵌套内部 .zip 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55763474/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com