如何使用SharpZipLib将ZipFile写入磁盘 [英] How do you write a ZipFile to disk using SharpZipLib

查看:86
本文介绍了如何使用SharpZipLib将ZipFile写入磁盘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  • 是否需要打开输出流才能将ZipFile写入磁盘?
  • 有什么方法可以获取ZipFile字节并执行File.WriteAllBytes()吗?

注意:我的问题不是关于压缩.只需获取现有的ZipFile并将其写入磁盘.

另外,请注意,我已经阅读过文档,并且此用例不存在.

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

解决方案

是否需要打开输出流才能将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();
}

How do you write a ZipFile to disk using SharpZipLib?

  • Do you have to open an output stream to write a ZipFile to disk?
  • Is there some way to just get the ZipFile bytes and do File.WriteAllBytes()?

Note: My question is not about compression. Just about taking an existing ZipFile and writing it to disk.

Also, please note, I have already perused docs and this use case is not there.

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

解决方案

Do you have to open an output stream to write a ZipFile to disk?

According to their Github samples, they are suggesting to create a stream object using ZipOutputStream to write the file and to write into the file being zipped, you need to open a FileStream to write the objects into the library.

Here is the sample of the code that you can use to zip files.

// 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();
}

Is there some way to just get the ZipFile bytes and do File.WriteAllBytes()?

If you are asking if we can write bytes of the files directly without opening the FileStream to read the files that are to be written in the zip file, then, Yes, you can write all bytes at once into the source zip file but that is a bad way as it will read all the bytes at once into the memory and this could be disastrous if the files being zipped are huge in size. Anyways, here is how you can do it:

Just replace the FileStream part in the above sample with this code:

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

So, the updated source code would be:

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();
}

这篇关于如何使用SharpZipLib将ZipFile写入磁盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆