主题:C#调用SharpZipLib压缩文件夹
xtwvfp
[专家分:0] 发布于 2006-05-22 15:29:00
大家好,我想问个问题
我用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个回复)
沙发
jzyray [专家分:20610] 发布于 2006-05-22 19:15:00
你没有给出关于AddZipEntry的代码,所以不能指出更改方法。(或者AddZipEntry应该是ZipFileMain)
可以参照一下#ZipLib的开发参考,关于ZipEntry是否是文件夹的依据是:名称末尾是斜杠,或者更改ExternalFileAttributes属性的值。
板凳
xtwvfp [专家分:0] 发布于 2006-05-23 09:25:00
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 楼
jzyray [专家分:20610] 发布于 2006-05-23 09:35:00
这样写应该是可以压缩文件夹的。
你的程序的初衷是将一个目录中的所有东西压缩到一个文件吗?我目前的理解是这样。
如果如此的话,最好把压缩文件和压缩文件夹的代码合并在一起,遍历文件夹的时候顺便把本层的文件都加入ZipStream中。
4 楼
xtwvfp [专家分:0] 发布于 2006-05-23 11:05:00
对!我的程序就是将目录中的所有东西压缩到一个文件,
我写的一个输出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 楼
jzyray [专家分:20610] 发布于 2006-05-23 12:21:00
错误具体信息是什么?
6 楼
xtwvfp [专家分:0] 发布于 2006-05-23 12:32:00
ZipOutputStream u = new ZipOutputStream(File.Create(args[0]));
报错
::::确保列表中的最大索引小于列表的大小;
确保数据列名称正确
请帮我分析一下
7 楼
jzyray [专家分:20610] 发布于 2006-05-23 13:31:00
你运行程序时传给它参数了吗
8 楼
xtwvfp [专家分:0] 发布于 2006-05-23 13:46:00
我没有传参数啊,我就想让你帮我修改一下我写的main
实在不写不出来了,想请你帮忙
9 楼
jzyray [专家分:20610] 发布于 2006-05-23 15:47:00
你程序这样写就是要传入两个参数。
要改的话,把那两个File.Create变成你真正需要输出流的文件。
10 楼
xtwvfp [专家分:0] 发布于 2006-05-23 18:17:00
老大还是不懂啊,我的程序都写在上面了,就是不知道怎么改,
请老大帮忙
我来回复