【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;