【问题标题】:DotNetZip - reading to memoryDotNetZip - 读取内存
【发布时间】:2011-03-25 07:54:04
【问题描述】:

我使用 DotNetZip 库进行了快速测试,该库打开了一个包含 .bmp 文件的 zip 文件并将它们转换为 .jpg 格式。

在此之前,我将所有文件写入一个文件夹,转换它们,保存 jpg 文件,然后删除原始的 bmp 文件,这变得一团糟。

我不想先将它们解压缩到内存中,然后转换为 jpg 然后保存。

代码有效,但速度不快。任何人都可以给我任何关于我可以做些什么来改进代码的指示吗?另外,线程有帮助吗?

string zipToUnpack = "c:\\test\\1000.zip";
string unpackDirectory = "c:\\temp\\";

string f = string.Empty;
Bitmap bm;
MemoryStream ms;

using (ZipFile zip = ZipFile.Read(zipToUnpack))
{                 
  foreach (ZipEntry e in zip)
  {
    if (e.FileName.ToLower().IndexOf(".bmp") > 0)
    {
      ms = new MemoryStream();
      e.Extract(ms);
      try
      {
        bm = new Bitmap(ms);                              
        f = unpackDirectory + e.FileName.ToLower().Replace(".bmp", ".jpg");
        bm.Save(f, System.Drawing.Imaging.ImageFormat.Jpeg);
      }
      catch (Exception ex)
      {
        Console.WriteLine("File: " + e.FileName + " " + ex.ToString());
      }
      ms.Dispose();
    }
  }
}

谢谢

【问题讨论】:

  • 慢的部分是什么? dijksterhuis.org/timing-function-performance-stopwatch-class 应该可以帮助您找出答案。
  • 感谢秒表。它在 1 分钟内转换 1000 张图像。我只是想知道是否有人有任何改进整体设计的想法。我很确定转换为 jpg 是缓慢的部分。我不确定线程​​是否会有所帮助,或者即使我可以在这种情况下应用它?
  • 我不明白你会如何应用线程。需要按顺序读取 zip,因此如果没有首先解压缩然后转换的初始解决方案,您将无法跨线程分配负载。即便如此,线程也是让 cpu 做更多的工作。但是如果你的硬盘跟不上,线程是没有用的。
  • 如果瓶颈在于位图读取、jpeg 创建甚至 jpeg 写入线程会有所帮助,那么这就是秒表有用的地方。如果瓶颈是解压缩部分,您需要一个能够执行此操作的 zip 库和一个未压缩在“实体”存档中的 zip 文件

标签: c# dotnetzip


【解决方案1】:

一般来说,DotNetZip 是单线程的。您可以在多个线程中打开多个存档,但每个存档只能在一个线程中。

如果您想加入多个 CPU 或内核,那么我建议您调用 QueueUserWorkItem 将 MemoryStream 中的数据转换为 jpg 的部分。

对于所有条目,ZipEntry.Extract() 的调用需要在同一个线程上完成。这是因为 Zipfile 为所有读取访问维护了一个 FileStream,多个线程提取条目会导致文件指针算术错误。

所以,是这样的:

    public class State
    {
        public string FileName;
        public MemoryStream stream;
    }

    public void Run()
    {
        string unpackDirectory = "c:\\temp\\";
        string zipToUnpack = "c:\\test\\1000.zip";

        var ConvertImage = new WaitCallback( (o) => {
                State s = o as State;
                try
                {
                    var bm = new Bitmap(s.stream);
                    var f = unpackDirectory + s.FileName.ToLower().Replace(".bmp", ".jpg");
                    bm.Save(f, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("File: " + s.FileName + " " + ex.ToString());
                }
            });


        using (ZipFile zip = ZipFile.Read(zipToUnpack))
        {
            foreach (ZipEntry e in zip)
            {
                if (e.FileName.ToLower().IndexOf(".bmp") > 0)
                {
                    var ms = new MemoryStream();
                    e.Extract(ms);
                    ThreadPool.QueueUserWorkItem ( ConvertImage, 
                                                   new State {
                                                       FileName = e.FileName, stream = ms }
                                                   });                      
                }
            }
        }
    }

【讨论】:

    猜你喜欢
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多