【C#MVC】C#中将文件夹压缩然后下载
【C#MVC】C#中将文件夹压缩然后下载
遇到一个需求,因为大量的图片下载不方便。于是要求下载一个压缩包。这样就需要我们将服务器上的文件打包,然后下载。 参数:rootPath -> 将要压缩的根目录
设置全局变量,临时存放文件(files)和空目录(paths):
List<string> files = null;
List<string> paths = null;
protected void Page_Load(object sender, EventArgs e)
{
files = new List<string>();//初始化
paths = new List<string>();//初始化
}
private void GetAllDirectories(string rootPath)
{
string[] subPaths = Directory.GetDirectories(rootPath);//得到所有子目录
foreach (string path in subPaths)
{
GetAllDirectories(path);//对每一个字目录做与根目录相同的操作:即找到子目录并将当前目录的文件名存入List
}
string[] files = Directory.GetFiles(rootPath);//得到当前目录下的文件
foreach (string file in files)
{
this.files.Add(file);//将当前目录中的所有文件全名存入文件List
}
if (subPaths.Length == files.Length && files.Length == 0)//如果是空目录
{
this.paths.Add(rootPath);//记录空目录
}
}
2.压缩文件 destinationPath -> 压缩文件的存放目录+文件名(新建一个临时目录,下载之后即可清楚,减轻服务器压力)
compressLevel -> 压缩成度(0-9)
public void ZipFileFromDirectory(string rootPath, string destinationPath, int compressLevel)
{
GetAllDirectories(rootPath); //获取所有文件和空目录
//作用:便于我们找到的解压相对路径。
while (rootPath.LastIndexOf("/") + 1 == rootPath.Length)//检查路径是否以"\"结尾
{
rootPath = rootPath.Substring(0, rootPath.Length - 1);//如果是则去掉末尾的"\"
}
string rootMark = rootPath.Substring(0, rootPath.LastIndexOf("/") + 1);//得到当前路径的位置,以备压缩时将所压缩内容转变成相对路径。
//rootMark = rootMark + "/";//得到当前路径的位置,以备压缩时将所压缩内容转变成相对路径。
Crc32 crc = new Crc32();
ZipOutputStream outPutStream = new ZipOutputStream(File.Create(destinationPath+".zip"));
outPutStream.SetLevel(compressLevel); // 0 - store only to 9 - means best compression
foreach (string file in files)
{
FileStream fileStream = File.OpenRead(file);//打开压缩文件
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(file.Replace(rootMark, string.Empty));
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 = fileStream.Length;
fileStream.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
outPutStream.PutNextEntry(entry);
outPutStream.Write(buffer, 0, buffer.Length);
}
this.files.Clear();
foreach (string emptyPath in paths)
{
ZipEntry entry = new ZipEntry(emptyPath.Replace(rootMark, string.Empty) + "/");
outPutStream.PutNextEntry(entry);
}
this.paths.Clear();
outPutStream.Finish();
outPutStream.Close();
GC.Collect();
}
3.下载压缩文件
参数:fileRpath -> 压缩文件所在目录+压缩文件名+”.zip”
public void DownloadFile(string fileRpath)
{
Response.ClearHeaders();
Response.Clear();
Response.Expires = 0;
Response.Buffer = true;
Response.AddHeader("Accept-Language", "zh-tw");
string name = System.IO.Path.GetFileName(fileRpath);
System.IO.FileStream files = new FileStream(fileRpath, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] byteFile = null;
if (files.Length == 0)
{
byteFile = new byte[1];
}
else
{
byteFile = new byte[files.Length];
}
files.Read(byteFile, 0, (int)byteFile.Length);
files.Close();
Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(name, System.Text.Encoding.UTF8));
Response.ContentType = "application/octet-stream;charset=gbk";
Response.BinaryWrite(byteFile);
Response.End();
}
4.调用并清空缓存:
protected void btnDownload_Click(object sender, EventArgs e)
{
try
{
string filePathtmp = ConfigurationManager.AppSettings["xxx"].ToString().Trim();
string destinationPath = ConfigurationManager.AppSettings["sss"].ToString().Trim();
if (!Directory.Exists(destinationPath))
{
Directory.CreateDirectory(destinationPath);
}
string testFileName = txtBagNumber.Text.Trim();
if (!Directory.Exists(filePathtmp + testFileName +"/"))
{
throw new Exception("No Files!");
}
ZipFileFromDirectory(filePathtmp + testFileName + "/", destinationPath + testFileName , 8);
DownloadFile(destinationPath + testFileName + ".zip");
Directory.Delete(destinationPath, true); //清空
}
catch (Exception ex)
{
lblError.Text = ex.Message;
}
}
5.引用DLL:
添加引用:
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;