我使用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();
}
}
}
由于
答案 0 :(得分:3)
一般来说,DotNetZip是单线程的。您可以在多个线程中打开多个归档,但每个归档只在一个线程中。
如果您想要登记多个CPU或核心,那么我可以建议为将MemoryStream中的数据转换为jpg的部分调用QueueUserWorkItem。
对于所有条目,需要在同一个线程上完成对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 }
});
}
}
}
}