首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

小弟我在使用ICSharpCode.SharpZipLib进行目录压缩后,再解压缩是提示这个异常

2012-04-23 
我在使用ICSharpCode.SharpZipLib进行目录压缩后,再解压缩是提示这个错误我在使用ICSharpCode.SharpZipLib

我在使用ICSharpCode.SharpZipLib进行目录压缩后,再解压缩是提示这个错误
我在使用ICSharpCode.SharpZipLib进行目录压缩后,再解压缩是提示这个错误:
Size mismatch: 4294967295;126976 <-> 70202;126976
是在执行这句时: size = s.Read(data, 0, data.Length);//读入一个压缩块
报的错误。
我的源代码如下
//压缩
  /// 
  /// 递归压缩文件夹方法
  private static bool ZipFileDictory(string FolderToZip, ZipOutputStream s, string ParentFolderName)
  {
  bool res = true;
  string[] folders, filenames;
  ZipEntry entry = null;
  FileStream fs = null;
  Crc32 crc = new Crc32();
  try
  {//创建当前文件夹
  entry = new ZipEntry(Path.Combine(ParentFolderName, Path.GetFileName(FolderToZip) + "/")); //加上 “/” 才会当成是文件夹创建
  s.PutNextEntry(entry);
  s.Flush();
  //先压缩文件,再递归压缩文件夹 
  filenames = Directory.GetFiles(FolderToZip);
  foreach (string file in filenames)
  {
  //打开压缩文件
  fs = File.OpenRead(file);

  byte[] buffer = new byte[fs.Length];
  fs.Read(buffer, 0, buffer.Length);
  entry = new ZipEntry(Path.Combine(ParentFolderName, Path.GetFileName(FolderToZip) + "/" + Path.GetFileName(file)));

  entry.DateTime = DateTime.Now;
  entry.Size = fs.Length;
  fs.Close();
  crc.Reset();
  crc.Update(buffer);
  entry.Crc = crc.Value;
  s.PutNextEntry(entry);
  s.Write(buffer, 0, buffer.Length);
  }
  }
  catch
  {
  res = false;
  }
  finally
  {
  if (fs != null)
  {
  fs.Close();
  fs = null;
  }
  if (entry != null)
  {
  entry = null;
  }
  GC.Collect();
  GC.Collect(1);
  }


  folders = Directory.GetDirectories(FolderToZip);
  foreach (string folder in folders)
  {
  if (!ZipFileDictory(folder, s, Path.Combine(ParentFolderName, Path.GetFileName(FolderToZip))))
  {
  return false;
  }
  }

  return res;
  }
  /// 
  /// 压缩目录
  /// 
  /// 待压缩的文件夹,全路径格式
  /// 压缩后的文件名,全路径格式
  /// 
  private static bool ZipFileDictory(string FolderToZip, string ZipedFile, String Password)
  {
  bool res;
  if (!Directory.Exists(FolderToZip))
  {
  return false;
  }

  ZipOutputStream s = new ZipOutputStream(File.Create(ZipedFile));
  s.SetLevel(9);
  s.Password = Password;

  res = ZipFileDictory(FolderToZip, s, "");

  s.Finish();
  s.Close();

  return res;
  }

  /// 


  /// 压缩文件
  /// 
  /// 要进行压缩的文件名
  /// 压缩后生成的压缩文件名
  /// 
  private static bool ZipFile(string FileToZip, string ZipedFile, String Password)
  {
  //如果文件没有找到,则报错
  if (!File.Exists(FileToZip))
  {
  throw new System.IO.FileNotFoundException("指定要压缩的文件: " + FileToZip + " 不存在!");
  }
  //FileStream fs = null;
  FileStream ZipFile = null;
  ZipOutputStream ZipStream = null;
  ZipEntry ZipEntry = null;

  bool res = true;
  try
  {
  ZipFile = File.OpenRead(FileToZip);
  byte[] buffer = new byte[ZipFile.Length];
  ZipFile.Read(buffer, 0, buffer.Length);
  ZipFile.Close();

  ZipFile = File.Create(ZipedFile);
  ZipStream = new ZipOutputStream(ZipFile);
  ZipStream.Password = Password;
  ZipEntry = new ZipEntry(Path.GetFileName(FileToZip));
  ZipStream.PutNextEntry(ZipEntry);
  ZipStream.SetLevel(6);

  ZipStream.Write(buffer, 0, buffer.Length);
  }
  catch
  {
  res = false;
  }
  finally
  {
  if (ZipEntry != null)
  {
  ZipEntry = null;
  }
  if (ZipStream != null)
  {
  ZipStream.Finish();
  ZipStream.Close();
  }
  if (ZipFile != null)
  {
  ZipFile.Close();
  ZipFile = null;
  }
  GC.Collect();
  GC.Collect(1);
  }

  return res;
  }

  /// 
  /// 压缩文件 和 文件夹
  /// 
  /// 待压缩的文件或文件夹,全路径格式
  /// 压缩后生成的压缩文件名,全路径格式
  /// 
  public bool Zip(String FileToZip, String ZipedFile, String Password)
  {
  if (Directory.Exists(FileToZip))
  {
  return ZipFileDictory(FileToZip, ZipedFile, Password);
  }
  else if (File.Exists(FileToZip))
  {
  return ZipFile(FileToZip, ZipedFile, Password);
  }
  else
  {
  return false;
  }
  }


[解决办法]

C# code
using System;using System.Collections.Generic;using System.Text;using ZipHelper.ZipLib.Zip;using System.IO;using System.Diagnostics;using ZipHelper.ZipLib.Checksums;namespace ZipHelper.ZipLib{    public class CreateZipHelper    {        private static void GetDir(string sourcePath, List<string> filenames)        {            try            {                filenames.AddRange(Directory.GetFiles(sourcePath));                DirectoryInfo dir = new DirectoryInfo(sourcePath);                foreach (DirectoryInfo d in dir.GetDirectories())                {                    GetDir(d.FullName, filenames);                }            }            catch (Exception ex)            {                throw ex;            }        }        /// <summary>        /// Create File.        /// </summary>        /// <param name="zipFile">the destfile.</param>        /// <param name="filePath">the souce files Path.</param>        public static void CreateZipFile(string zipName, string souceFilesPath)        {            try            {                if (!Directory.Exists(souceFilesPath))                {                    Debug.WriteLine("Cannot find directory '{0}'", souceFilesPath);                    return;                }                // Depending on the directory this could be very large and would require more attention                // in a commercial package.                //string[] filenames = Directory.GetFiles(souceFilesPath);                List<string> filenames = new List<string>();                GetDir(souceFilesPath, filenames);                // 'using' statements gaurantee the stream is closed properly which is a big source                // of problems otherwise.  Its exception safe as well which is great.                using (ZipOutputStream s = new ZipOutputStream(File.Create(zipName)))                {                    s.SetLevel(9); // 0 - store only to 9 - means best compression                    byte[] buffer = new byte[4096];                    foreach (string file in filenames)                    {                        // Using GetFileName makes the result compatible with XP                        // as the resulting path is not absolute.                        string filename = file;                        if (filename.StartsWith("\\"))                        {                            filename = filename.Substring(1);                        }                        ZipEntry entry = new ZipEntry(filename);                        // Setup the entry data as required.                        // Crc and size are handled by the library for seakable streams                        // so no need to do them here.                        // Could also use the last write time or similar for the file.                        entry.DateTime = DateTime.Now;                        s.PutNextEntry(entry);                        using (FileStream fs = File.OpenRead(file))                        {                            // Using a fixed size buffer here makes no noticeable difference for output                            // but keeps a lid on memory usage.                            int sourceBytes;                            do                            {                                sourceBytes = fs.Read(buffer, 0, buffer.Length);                                s.Write(buffer, 0, sourceBytes);                            } while (sourceBytes > 0);                        }                                            }                    // Finish/Close arent needed strictly as the using statement does this automatically                    // Finish is important to ensure trailing information for a Zip file is appended.  Without this                    // the created file would be invalid.                    s.Finish();                    // Close is important to wrap things up and unlock the file.                    s.Close();                }            }            catch (Exception ex)            {                Console.WriteLine("Exception during processing {0}", ex);                // No need to rethrow the exception as for our purposes its handled.            }        }}} 


[解决办法]
如果有源码的话可以这样做:
在项目所引用库“ICSharpCode.SharpZipLib.dll”的ICSharpCode.SharpZipLib.Zip.Compression. ZipInputStream.cs类中找到抛出异常的代码段:
int BodyRead(byte[] buffer, int offset, int count)
{
...
if ((flags & 8) == 0 && (inf.TotalIn != csize || inf.TotalOut != size)) {
throw new ZipException("Size mismatch: " + csize + ";" + size + " <-> " + inf.TotalIn + ";" + inf.TotalOut);
}
...
return count;
}

if ((flags & 8) == 0 && (inf.TotalIn != csize || inf.TotalOut != size)) {
throw new ZipException("Size mismatch: " + csize + ";" + size + " <-> " + inf.TotalIn + ";" + inf.TotalOut);
}
注释掉即可,解压和压缩一切都正常。

热点排行