我使用DotNetZip库进行了一个快速测试,该库打开一个包含.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();
}
}
}谢谢
发布于 2011-03-11 10:16:31
一般来说,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 }
});
}
}
}
}https://stackoverflow.com/questions/5266883
复制相似问题