使用SharpZip压缩与解压缩的实战经验

  • Post author:
  • Post category:其他








使用SharpZip压缩与解压缩的实战经验

















作者:寒羽枫

这篇文章原是我在


CSDN



论坛发的一篇帖子(




http://search.csdn.net/expert/topicview1.asp?id=2377844




),现把它“顺”(整)理成章。















首先,在



http://www.icsharpcode.net/OpenSource/SharpZipLib/Default.aspx



下载源码,找到“ZipConstants.cs”修改


public

static

string

ConvertToString(

byte

[] data)

{



return

Encoding.GetEncoding(“gb2312”).GetString(data, 0, data.Length);


//return Encoding.ASCII.GetString(data,0, data.Length);


}


public

static

byte

[] ConvertToArray(

string

str)

{



return

Encoding.GetEncoding(“gb2312”).GetBytes(str);


//return Encoding.ASCII.GetBytes(str);


}




如此就可支持中文名称了

以下是我写的压缩与解压缩的代码:


using

System;


using

System.Collections;


using

System.ComponentModel;


using

System.Data;


using

System.Drawing;


using

System.Web;


using

System.Web.SessionState;


using

System.Web.UI;


using

System.Web.UI.WebControls;


using

System.Web.UI.HtmlControls;


using

ICSharpCode.SharpZipLib.Zip;




namespace OA

{


/// <summary>

///

WebForm1 的摘要说明。


/// </summary>


public

class WebForm1 : System.Web.UI.Page

{



public


string

ServerDir;


private


void

Page_Load(

object

sender, System.EventArgs e)

{



// 在此处放置用户代码以初始化页面



this

.ServerDir = Page.MapPath(“.”);


this

.ZipFile(“01.txt*02.txt*000.zip”);

//只是示例,具体的大家自己去实现



this

.ZipFile(“01.txt*02.txt*001.zip”);


this

.UnZipFile(“000.zip*001.zip”);

}


public


string

ShortDir(

string

s)

{



//将文件的绝对路径转为相对路径



string

d=s.Replace(ServerDir,””);


return

d;

}







//压缩文件 p 为客户端传回来的文件列表:文件名+压缩包的名称



public


void

ZipFile(

string

p)

{



string

[] tmp = p.Split(

new


char

[]{‘*’});

//分离文件列表



if

(tmp[tmp.Length-1]!=””)

//压缩包名称不为空


{


ZipOutputStream u =

new

ZipOutputStream(File.Create(ServerDir+tmp[tmp.Length-1]));

//新建压缩文件流 “ZipOutputStream”



for

(

int

i =0;i<tmp.Length-1;i++)

{



if

(tmp[i]!=””)

//分离出来的文件名不为空


{



this

.AddZipEntry(tmp[i],u,


out


u);

//向压缩文件流加入内容


}

}

u.Finish();

// 结束压缩


u.Close();

}

}





//添加压缩项目:p 为需压缩的文件或文件夹; u 为现有的源ZipOutputStream;

out

j为已添加“ZipEntry”的“ZipOutputStream”



public


void

AddZipEntry(

string

p,ZipOutputStream u,

out

ZipOutputStream j)

{



string

s =ServerDir+p;




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();

}

j=u;

//返回已添加数据的“ZipOutputStream”


}





public


void

UnZipFile(

string

p)

//解压缩


{



string

[] un_tmp = p.Split(

new


char

[]{‘*’});


int

i2=0;

//防止名称冲突的参数



for

(

int

j=0;j<un_tmp.Length;j++)

{



if

(un_tmp[j]!=””)

{



string

un_time=System.DateTime.Now.ToShortDateString()+”-“+System.DateTime.Now.Hour.ToString()+”-“+System.DateTime.Now.Minute.ToString()+”-“+(System.DateTime.Now.Second+i2).ToString();


string

un_dir =ServerDir+”Unzip-“+un_time;

Directory.CreateDirectory(un_dir);

//创建以解压时间为名称的文件夹


ZipInputStream f =

new

ZipInputStream(File.OpenRead(ServerDir+un_tmp[j]));

//读取压缩文件,并用此文件流新建 “ZipInputStream”对象




A:  ZipEntry zp = f.GetNextEntry();

//获取解压文件流中的项目。 另注(我的理解):在压缩包里每个文件都以“ZipEntry”形式存在,其中包括存放文件的目录信息。如果空目录被压缩,该目录下将出现一个名称为空、大小为 0 、“Crc”属性为 00000000 的“文件”。此文件只是个标记,不会被解压。





while

(zp!=null)

{



string

un_tmp2;


if

(zp.Name.IndexOf(”


//”)>=0


)

//获取文件的目录信息


{



int

tmp1 = zp.Name.LastIndexOf(“//”);

un_tmp2 = zp.Name.Sub

string

(0,tmp1);

Directory.CreateDirectory(un_dir+”


//”+un_tmp2+”//


“);

//必须先创建目录,否则解压失败 — (A) 关系到下面的步骤(B)


}


if

(!zp.IsDirectory&&zp.Crc!=00000000L)

//此“ZipEntry”不是“标记文件”


{



int

i =2048;


byte

[] b =

new


byte

[i];

//每次缓冲 2048 字节


FileStream s= File.Create(un_dir+”


//”+zp.Name


);

//(B)-新建文件流



while

(

true

)

//持续读取字节,直到一个“ZipEntry”字节读完


{


i = f.Read(b,0,b.Length);

//读取“ZipEntry”中的字节



if

(i>0)

{


s.Write(b,0,i);

//将字节写入新建的文件流


}


else


{



break

;

//读取的字节为 0 ,跳出循环


}

}

s.Close();

}


goto

A;

//进入下一个“ZipEntry”


}

f.Close();

i2++;

}

}

}

}

}






版权声明:本文为cityhunter172原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。