【问题标题】:How do you write a ZipFile to disk using SharpZipLib [closed]如何使用 SharpZipLib 将 ZipFile 写入磁盘 [关闭]
【发布时间】:2020-11-02 22:26:09
【问题描述】:

如何使用 SharpZipLib 将ZipFile 写入磁盘?

  • 是否必须打开输出流才能将ZipFile 写入磁盘?
  • 有没有办法只获取ZipFile 字节并执行File.WriteAllBytes()

注意:我的问题与压缩无关。只需将现有的ZipFile 写入磁盘即可。

另外,请注意,我已经阅读过文档,但没有这个用例。

https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples

【问题讨论】:

  • @RetiredNinja 所以在发布之前我已经浏览了这些示例。他们没有保存 zip 的示例 - 以完整的 ZipFile 开头。我不是在谈论压缩文件 - 只是将 ZipFile 保存到磁盘。
  • 获取现有的 zip 文件并将其写入磁盘?它不是已经在磁盘上了吗?如果不是,它在哪里?是字节吗?
  • @ina 如果您不在问题中提供更多细节,此问题将被关闭。目前还不清楚你在问什么。不过,我相信如果你能弄清楚基本点,这可以在几秒钟内得到回答……你从哪里得到这个 zip 文件。如果它来自再见,只需使用File 方法将其写入磁盘,如果它来自流,则只需使用FileStream 将其写入磁盘。如果它已经在磁盘上,只需使用File.Copy
  • @TheGeneral 不,它不在磁盘上。它可以作为 SharpZipLib ZipFile

标签: c# file zip sharpziplib


【解决方案1】:

是否必须打开输出流才能将 ZipFile 写入磁盘?

根据他们的Github 示例,他们建议使用ZipOutputStream 创建一个流对象来写入文件并写入正在压缩的文件中,您需要打开一个FileStream 将对象写入图书馆。

这是可用于压缩文件的代码示例。

// Depending on the directory this could be very large and would require more attention
// in a commercial package.
string[] filenames = Directory.GetFiles("directory");

// 'using' statements guarantee the stream is closed properly which is a big source
// of problems otherwise.  Its exception safe as well which is great.
using (ZipOutputStream s = new ZipOutputStream(File.Create("outputfile")))
{

    s.SetLevel(9); // 0 - store only to 9 - means best compression

    byte[] buffer = new byte[4096];

    foreach (string file in filenames)
    {

        // Using GetFileName makes the result compatible with XP
        // as the resulting path is not absolute.
        var entry = new ZipEntry(Path.GetFileName(file));

        // Setup the entry data as required.

        // Crc and size are handled by the library for seakable streams
        // so no need to do them here.

        // Could also use the last write time or similar for the file.
        entry.DateTime = DateTime.Now;
        s.PutNextEntry(entry);

        using (FileStream fs = File.OpenRead(file)) 
        {

            // Using a fixed size buffer here makes no noticeable difference for output
            // but keeps a lid on memory usage.
            int sourceBytes;
            do
            {
            sourceBytes = fs.Read(buffer, 0, buffer.Length);
            s.Write(buffer, 0, sourceBytes);
            } while (sourceBytes > 0);
        }
    }

    // Finish/Close arent needed strictly as the using statement does this automatically

    // Finish is important to ensure trailing information for a Zip file is appended.  Without this
    // the created file would be invalid.
    s.Finish();

    // Close is important to wrap things up and unlock the file.
    s.Close();
}

有什么方法可以获取 ZipFile 字节并执行 File.WriteAllBytes()?

如果您问我们是否可以直接写入文件的字节而不打开FileStream 来读取要写入 zip 文件中的文件,那么,是的,您可以一次将所有字节写入源zip 文件,但这是一种不好的方法,因为它会一次将所有字节读入内存,如果被压缩的文件很大,这可能是灾难性的。无论如何,这是你可以做到的:

只需将上述示例中的FileStream 部分替换为以下代码即可:

var bytes = File.ReadAllBytes(file);
s.Write(bytes, 0, bytes.Length); // write all bytes from 0 to the length of the bytes

因此,更新后的源代码将是:

string[] filenames = Directory.GetFiles("directory");

using (ZipOutputStream s = new ZipOutputStream(File.Create("outputfile")))
{

    s.SetLevel(9);

    byte[] buffer = new byte[4096];

    foreach (string file in filenames)
    {
        var entry = new ZipEntry(Path.GetFileName(file));

        entry.DateTime = DateTime.Now;
        s.PutNextEntry(entry);
        var bytes = File.ReadAllBytes(file);
        s.Write(bytes, 0, bytes.Length);
    }
    s.Finish();
    s.Close();
}

【讨论】:

  • 这对我不起作用,因为这些情况都不适用。我正在尝试将一个从闭源 SDK 传递的ZipFile 写入磁盘。
  • 为此,您必须告诉我们该 zip 文件是如何通过流、字节或其他方式传递的?
  • ZipFile 是 SharpZipLib 中的对象类型。您可以在 zip 文件中遍历其ZipEntry,其中zipFile.GetInputStream(zipEntry) 为您获取每个文件的流......它作为ZipFile 对象传递。但是,我似乎无法通过该方法访问字节 stackoverflow.com/questions/64668726/…
猜你喜欢
  • 2014-03-09
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多