2011-01-19 137 views
5

ZipOutputStream只能将文件夹中的文件压缩。我也想压缩子文件夹。我怎样才能做到这一点?使用ZipOutputStream的Zip子文件夹

+2

我希望你没有抛弃这个问题,将回到纪念答案

或至少指出哪些答案是有用的。在你的200多个问题中,你将有大约120个需要答案的标记(如果答案令人满意),每个标记的答案将为你赢得额外的2个代表点,并帮助你的问题的未来观众知道最佳答案是什么。 120 * 2rep = 240代表你可以获得。 – slugster 2012-06-09 03:34:53

回答

7

您必须递归探索您的目录才能在zip中添加所有文件。

见,如果你想这个小帮手:

using ICSharpCode.SharpZipLib.Zip; 
    using ICSharpCode.SharpZipLib.Checksums; 
    using System.IO; 
    using System; 
    using System.Collections.Generic; 
    using System.Text; 
    using System.Collections; 
    using System.Text.RegularExpressions; 

    namespace Zip 
{ 
    /// <summary> 
    /// Uses Sharpziplib so as to create a non flat zip archive 
    /// </summary> 
    public abstract class ZipManager 
    { 
     /// <summary> 
     /// will zip directory .\toto as .\toto.zip 
     /// </summary> 
     /// <param name="stDirToZip"></param> 
     /// <returns></returns> 
     public static string CreateZip(string stDirToZip) 
     { 
      try 
      { 
       DirectoryInfo di = new DirectoryInfo(stDirToZip); 
       string stZipPath = di.Parent.FullName + "\\" + di.Name + ".zip"; 

       CreateZip(stZipPath, stDirToZip); 

       return stZipPath; 
      } 
      catch (Exception) 
      { 
       throw; 
      } 
     } 

     /// <summary> 
     /// Main method 
     /// </summary> 
     /// <param name="stZipPath">path of the archive wanted</param> 
     /// <param name="stDirToZip">path of the directory we want to create, without ending backslash</param> 
     public static void CreateZip(string stZipPath, string stDirToZip) 
     { 
      try 
      { 
       //Sanitize inputs 
       stDirToZip = Path.GetFullPath(stDirToZip); 
       stZipPath = Path.GetFullPath(stZipPath); 

       Console.WriteLine("Zip directory " + stDirToZip); 

       //Recursively parse the directory to zip 
       Stack<FileInfo> stackFiles = DirExplore(stDirToZip); 

       ZipOutputStream zipOutput = null; 

       if (File.Exists(stZipPath)) 
        File.Delete(stZipPath); 

       Crc32 crc = new Crc32(); 
       zipOutput = new ZipOutputStream(File.Create(stZipPath)); 
       zipOutput.SetLevel(6); // 0 - store only to 9 - means best compression 

       Console.WriteLine(stackFiles.Count + " files to zip.\n"); 

       int index = 0; 
       foreach (FileInfo fi in stackFiles) 
       { 
        ++index; 
        int percent = (int)((float)index/((float)stackFiles.Count/100)); 
        if (percent % 1 == 0) 
        { 
         Console.CursorLeft = 0; 
         Console.Write(_stSchon[index % _stSchon.Length].ToString() + " " + percent + "% done."); 
        } 
        FileStream fs = File.OpenRead(fi.FullName); 

        byte[] buffer = new byte[fs.Length]; 
        fs.Read(buffer, 0, buffer.Length); 

        //Create the right arborescence within the archive 
        string stFileName = fi.FullName.Remove(0, stDirToZip.Length + 1); 
        ZipEntry entry = new ZipEntry(stFileName); 

        entry.DateTime = DateTime.Now; 

        // set Size and the crc, because the information 
        // about the size and crc should be stored in the header 
        // if it is not set it is automatically written in the footer. 
        // (in this case size == crc == -1 in the header) 
        // Some ZIP programs have problems with zip files that don't store 
        // the size and crc in the header. 
        entry.Size = fs.Length; 
        fs.Close(); 

        crc.Reset(); 
        crc.Update(buffer); 

        entry.Crc = crc.Value; 

        zipOutput.PutNextEntry(entry); 

        zipOutput.Write(buffer, 0, buffer.Length); 
       } 
       zipOutput.Finish(); 
       zipOutput.Close(); 
       zipOutput = null; 
      } 
      catch (Exception) 
      { 
       throw; 
      } 
     } 


     static private Stack<FileInfo> DirExplore(string stSrcDirPath) 
     { 
      try 
      { 
       Stack<DirectoryInfo> stackDirs = new Stack<DirectoryInfo>(); 
       Stack<FileInfo> stackPaths = new Stack<FileInfo>(); 

       DirectoryInfo dd = new DirectoryInfo(Path.GetFullPath(stSrcDirPath)); 

       stackDirs.Push(dd); 
       while (stackDirs.Count > 0) 
       { 
        DirectoryInfo currentDir = (DirectoryInfo)stackDirs.Pop(); 

        try 
        { 
         //Process .\files 
         foreach (FileInfo fileInfo in currentDir.GetFiles()) 
         { 
          stackPaths.Push(fileInfo); 
         } 

         //Process Subdirectories 
         foreach (DirectoryInfo diNext in currentDir.GetDirectories()) 
          stackDirs.Push(diNext); 
        } 
        catch (Exception) 
        {//Might be a system directory 
        } 
       } 
       return stackPaths; 
      } 
      catch (Exception) 
      { 
       throw; 
      } 
     } 

     private static char[] _stSchon = new char[] { '-', '\\', '|', '/' }; 
    } 
} 
+0

这不会压缩子文件夹,我想在zip压缩文件夹中添加文件夹。 – BreakHead 2011-01-19 11:24:32

+0

你试过这段代码吗?它很好地压缩子文件夹(请参阅DirExplore方法) – Vinzz 2011-01-19 13:38:32

0

替代(和更方便的)解决方案,我只是偶然发现:使用SevenZipSharp项目

var compressor = new SevenZipCompressor(); 
compressor.ArchiveFormat = OutArchiveFormat.SevenZip; 
compressor.CompressionLevel = CompressionLevel.High; 
compressor.CompressionMode = CompressionMode.Create; 
compressor.PreserveDirectoryRoot = false; 
compressor.FastCompression = true; 
compressor.CompressDirectory(dir.FullName, zipFile.FullName); 
3
public static void ZipDirectoryKeepRelativeSubfolder(string zipFilePath, string directoryToZip) 
{ 
    var filenames = Directory.GetFiles(directoryToZip, "*.*", SearchOption.AllDirectories); 
    using (var s = new ZipOutputStream(File.Create(zipFilePath))) 
    { 
     s.SetLevel(9);// 0 - store only to 9 - means best compression 

     var buffer = new byte[4096]; 

     foreach (var file in filenames) 
     { 
      var relativePath = file.Substring(directoryToZip.Length).TrimStart('\\'); 
      var entry = new ZipEntry(relativePath); 
      entry.DateTime = DateTime.Now; 
      s.PutNextEntry(entry); 

      using (var fs = File.OpenRead(file)) 
      { 
       int sourceBytes; 
       do 
       { 
        sourceBytes = fs.Read(buffer, 0, buffer.Length); 
        s.Write(buffer, 0, sourceBytes); 
       } while (sourceBytes > 0); 
      } 
     } 
     s.Finish(); 
     s.Close(); 
    } 
} 
相关问题