DotNetZip - чтение в память

Я собрал быстрый тест с использованием библиотеки DotNetZip, которая открывает zip-файл, полный.bmp-файлов, и преобразует их в формат.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();
    }
  }
}

Спасибо

1 ответ

Решение

В общем, DotNetZip является однопоточным. Вы можете открыть несколько архивов в нескольких потоках, но каждый архив только в одном потоке.

Если вы хотите подключить несколько процессоров или ядер, то я могу предложить вызвать 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 }
                                                   });                      
                }
            }
        }
    }
Другие вопросы по тегам