回 帖 发 新 帖 刷新版面

主题:C#调用SharpZipLib压缩文件夹

大家好,我想问个问题
我用ICSharpZipLib类进行文件解压缩时,只能压缩文件夹里面的子文件,如果有子文件夹却不能压缩.
能帮我解决一下吗,下面是我的程序,
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.IO; 
using System.IO.Compression; 
using System.ComponentModel; 
using ICSharpCode.SharpZipLib.Checksums; 
using ICSharpCode.SharpZipLib.Zip; 
using ICSharpCode.SharpZipLib.GZip; 
using System.Diagnostics; 

namespace SharpZipLib 


class Program 

public void ZipFile(string FileToZip, string ZipedFile, int CompressionLevel, int BlockSize) 

//如果文件没有找到,则报错 
if (!System.IO.File.Exists(FileToZip)) 

throw new System.IO.FileNotFoundException("The specified file " + FileToZip + " could not be found. Zipping aborderd"); 


System.IO.FileStream StreamToZip = new System.IO.FileStream(FileToZip, System.IO.FileMode.Open, System.IO.FileAccess.Read); 
System.IO.FileStream ZipFile = System.IO.File.Create(ZipedFile); 
ZipOutputStream ZipStream = new ZipOutputStream(ZipFile); 
ZipEntry ZipEntry = new ZipEntry("ZippedFile"); 
ZipStream.PutNextEntry(ZipEntry); 
ZipStream.SetLevel(CompressionLevel); 
byte[] buffer = new byte[BlockSize]; 
System.Int32 size = StreamToZip.Read(buffer, 0, buffer.Length); 
ZipStream.Write(buffer, 0, size); 
try 

while (size < StreamToZip.Length) 

int sizeRead = StreamToZip.Read(buffer, 0, buffer.Length); 
ZipStream.Write(buffer, 0, sizeRead); 
size += sizeRead; 


catch (System.Exception ex) 

throw ex; 

ZipStream.Finish(); 
ZipStream.Close(); 
StreamToZip.Close(); 


public void ZipFileMain(string[] args)//对文件进行压缩; 

string[] filenames = Directory.GetFiles(args[0]); 

Crc32 crc = new Crc32(); 
ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));//新建压缩文件流 “ZipOutputStream” 

s.SetLevel(6); // 0 - store only to 9 - means best compression 

foreach (string file in filenames) 

//打开要压缩的文件 
FileStream fs = File.OpenRead(file); 

byte[] buffer = new byte[fs.Length]; 
fs.Read(buffer, 0, buffer.Length); 
ZipEntry entry = new ZipEntry(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); 


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

public static string ServerDir; 
static void Main(string[] args) 

int month = Convert.ToInt32(DateTime.Now.ToString("MM"));//只取当前月份; 
int iOldMonth = month - 1; 
string a = iOldMonth.ToString(); 
string year = DateTime.Now.ToString("yyyy");//只取当前年份; 
string time = Convert.ToString (year + "-" + a); 
System.Console.WriteLine(time); 
string abc = "c://unzipped/" + time; 
string[] FileProperties = new string[2]; 
FileProperties[0] = abc;//待压缩文件目录 
ServerDir = FileProperties[0]; 
//ServerDir = Path.GetDirectoryName("."); 
System.Console.WriteLine(ServerDir); 
FileProperties[1] = "C://zip/a.zip"; //压缩后的目标文件 
Program Zc = new Program(); 
Zc.AddZipEntry(FileProperties); 

这个只能压缩我指定的文件夹里的子文件,文件夹里的子文件夹就不能压缩
请大家帮忙

回复列表 (共23个回复)

沙发

你没有给出关于AddZipEntry的代码,所以不能指出更改方法。(或者AddZipEntry应该是ZipFileMain)

可以参照一下#ZipLib的开发参考,关于ZipEntry是否是文件夹的依据是:名称末尾是斜杠,或者更改ExternalFileAttributes属性的值。

板凳

jzyray谢谢你的恢复
我现在下面在写一段AddZipEntry的代码你帮我看看可否能压缩文件夹:
你能帮我写一个在main输出时调用AddZipEntry的代码吗????
public void AddZipEntry(string p, ZipOutputStream u, out ZipOutputStream u_3)
        {
            
            string[] filenames = Directory.GetDirectories(ServerDir);
            string s = ServerDir + p;//设定一个目录,s是目录存放的路径
            Crc32 crc = new Crc32();
            if (Directory.Exists(s))  //文件夹的处理
            {
                DirectoryInfo di = new DirectoryInfo(s);

                if (di.GetDirectories().Length <= 0)   //没有子目录
                {
                    ZipEntry z = new ZipEntry(p + "//"); //末尾“\\”用于文件夹的标记
                    u.PutNextEntry(z);
                }


                foreach (DirectoryInfo tem in di.GetDirectories())  //获取子目录
                {
                    ZipEntry z = new ZipEntry(this.ShortDir(tem.FullName) + "//"); //末尾“\\”用于文件夹的标记
                    u.PutNextEntry(z);    //此句不可少,否则空目录不会被添加
                    s = this.ShortDir(tem.FullName);
                    this.AddZipEntry(s, u, out u);       //递归
                }
                foreach (FileInfo temp in di.GetFiles())  //获取此目录的文件
                {
                    s = this.ShortDir(temp.FullName);
                    this.AddZipEntry(s, u, out u);      //递归
                }
            }
            else if (File.Exists(s))  //文件的处理
            {
                u.SetLevel(9);      //压缩等级
                FileStream f = File.OpenRead(s);
                byte[] b = new byte[f.Length];
                f.Read(b, 0, b.Length);          //将文件流加入缓冲字节中
                ZipEntry z = new ZipEntry(this.ShortDir(s));
                u.PutNextEntry(z);             //为压缩文件流提供一个容器
                u.Write(b, 0, b.Length);  //写入字节
                f.Close();
            }
            u_3 = u;    //返回已添加数据的“ZipOutputStream”
            
        }

我很急请大家多帮帮忙

3 楼

这样写应该是可以压缩文件夹的。

你的程序的初衷是将一个目录中的所有东西压缩到一个文件吗?我目前的理解是这样。

如果如此的话,最好把压缩文件和压缩文件夹的代码合并在一起,遍历文件夹的时候顺便把本层的文件都加入ZipStream中。

4 楼

对!我的程序就是将目录中的所有东西压缩到一个文件,
我写的一个输出main但就是报错:
我在发给你看看
 static void Main(string[] args)
        {
            
            int month = Convert.ToInt32(DateTime.Now.ToString("MM"));//只取当前月份;
            int iOldMonth = month - 1;
            ipOutputStream u = new ZipOutputStream(File.Create(args[0]));****此处报错(请你帮我改改)
            ZipOutputStream u_3 = new ZipOutputStream(File.Create(args[1]));
            string a = iOldMonth.ToString();
            string year = DateTime.Now.ToString("yyyy");//只取当前年份;
            string time = Convert.ToString (year + "-" + a);
            System.Console.WriteLine(time);
            string abc = "c://unzipped/" + time;
            string[] FileProperties = new string[2];
            FileProperties[0] = abc;//待压缩文件目录
            ServerDir = FileProperties[0];
            ServerDir = Path.GetDirectoryName(".");
            FileProperties[1] = "C://zip/a.zip";  //压缩后的目标文件
            Program Zc = new Program();
            Zc.AddZipEntry(ServerDir , u, out u_3);
    }
  public static string ServerDir;
  public string ShortDir(string s)
        {
           //将文件的绝对路径转为相对路径
           string d = s.Replace(ServerDir, "");
            return d;
        }
public void AddZipEntry(string p, ZipOutputStream u, out ZipOutputStream u_3)
        {
            
            string[] filenames = Directory.GetDirectories(ServerDir);
            string s = ServerDir + p;//设定一个目录,s是目录存放的路径
            Crc32 crc = new Crc32();
            if (Directory.Exists(s))  //文件夹的处理
            {
                DirectoryInfo di = new DirectoryInfo(s);

                if (di.GetDirectories().Length <= 0)   //没有子目录
                {
                    ZipEntry z = new ZipEntry(p + "//"); //末尾“\\”用于文件夹的标记
                    u.PutNextEntry(z);
                }


                foreach (DirectoryInfo tem in di.GetDirectories())  //获取子目录
                {
                    ZipEntry z = new ZipEntry(this.ShortDir(tem.FullName) + "//"); //末尾“\\”用于文件夹的标记
                    u.PutNextEntry(z);    //此句不可少,否则空目录不会被添加
                    s = this.ShortDir(tem.FullName);
                    this.AddZipEntry(s, u, out u);       //递归
                }
                foreach (FileInfo temp in di.GetFiles())  //获取此目录的文件
                {
                    s = this.ShortDir(temp.FullName);
                    this.AddZipEntry(s, u, out u);      //递归
                }
            }
            else if (File.Exists(s))  //文件的处理
            {
                u.SetLevel(9);      //压缩等级
                FileStream f = File.OpenRead(s);
                byte[] b = new byte[f.Length];
                f.Read(b, 0, b.Length);          //将文件流加入缓冲字节中
                ZipEntry z = new ZipEntry(this.ShortDir(s));
                u.PutNextEntry(z);             //为压缩文件流提供一个容器
                u.Write(b, 0, b.Length);  //写入字节
                f.Close();
            }
            u_3 = u;    //返回已添加数据的“ZipOutputStream”
            
        }



5 楼

错误具体信息是什么?

6 楼

ZipOutputStream u = new ZipOutputStream(File.Create(args[0]));
报错
::::确保列表中的最大索引小于列表的大小;
    确保数据列名称正确

请帮我分析一下

7 楼

你运行程序时传给它参数了吗

8 楼

我没有传参数啊,我就想让你帮我修改一下我写的main
实在不写不出来了,想请你帮忙

9 楼

你程序这样写就是要传入两个参数。

要改的话,把那两个File.Create变成你真正需要输出流的文件。

10 楼

老大还是不懂啊,我的程序都写在上面了,就是不知道怎么改,
请老大帮忙

我来回复

您尚未登录,请登录后再回复。点此登录或注册