上周有同事反映早前写的程序在进行解压操作时偶尔会出现异常。该程序是用C#编写的,.net framework版本是3.5,使用的压缩解压功能来自于Ionic.Zip这个程序集,当时主要使用该程序集对多个文件和文件夹进行压缩和解压操作。
同事遇到的解压报错是“bad read of entry server XXX.dll from compressed archive ”,在stackoverflow上找到一个类似的问题(参考文章1),回答中说可能跟文件大小有关系,Ionic.Zip.dll中在压缩某些特定大小的文件时会出错,于是使用fsutil命令行命令创建了一个与同事报错文件大小相同的文件进行测试。
在命令行中使用fsutil file createnew命令可以创建指定大小的文件,具体的语法是fsutil file [createnew] FileName Length,其中FileName是文件的全路径名称(带后缀名),Length是文件大小,单位是字节。通过该命令创建指定大小的文件进行压缩解压测试。
文件压缩代码如下:
using (var zip = new ZipFile(Encoding.Default))
{
if (System.IO.File.Exists(txtFilePath.Text))
{
zip.AddFile(txtFilePath.Text);
}
zip.Save(DEFAULT_ZIP_FILE_NAME);
System.Diagnostics.Process.Start("explorer.exe", Application.StartupPath);
}
文件解压测试代码如下:
using (var zip = new ZipFile(DEFAULT_ZIP_FILE_NAME))
{
zip.ExtractAll(Application.StartupPath,true);
}
通过测试,并没有发现同事遇到的问题,可能是电脑环境不同或者是其它原因。根据参考文献1中的说法,把文件大小重新调整一下可能就会解决同事的问题☺。
调试代码的同时,顺便写了简单的使用Ionic.Zip同时压缩文件和文件夹的示例,主要代码没有多少,如下面所示:
using (var zip = new ZipFile(Encoding.Default))
{
if (System.IO.File.Exists(txtFilePath.Text))
{
zip.AddFile(txtFilePath.Text);
}
if (Directory.Exists(txtDirPath.Text))
{
DirectoryInfo di = new DirectoryInfo(txtDirPath.Text);
zip.AddDirectory(di.FullName,di.Name);
}
zip.Save(DEFAULT_ZIP_FILE_NAME);
System.Diagnostics.Process.Start("explorer.exe", Application.StartupPath);
}
程序界面如下图所示,压缩后的文件使用WinRAR进行解压测试也没有问题。
示例代码放在了GitHub上:https://github.com/guochao2299/IonicZipTest
参考文章:
[1]https://stackoverflow.com/questions/15337186/dotnetzip-badreadexception-on-extract
[2]https://baike.baidu.com/item/Fsutil/9818874