C-将服务器文件批量压缩打包下载至本地两种方法压缩包缓存到服务器下载压缩包缓存到内存下载
目录
C# 将服务器文件批量压缩打包下载至本地两种方法(压缩包缓存到服务器下载、压缩包缓存到内存下载)
1、将服务器文件打包下载至本地(压缩包缓存到服务器下载)
(1)文件批量压缩成压缩包并缓存到服务器(公共方法)
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
/// <summary>
/// 压缩文件(并保存至服务器)
/// </summary>
/// <param name="fileName">要压缩的所有文件(完全路径)</param>
/// <param name="name">压缩后文件路径</param>
/// <param name="Level">压缩级别</param>
public static bool ZipFileMain(List<string> filenames, string name, int Level){
ZipOutputStream s = new ZipOutputStream(File.Create(name));
Crc32 crc = new Crc32();
//压缩级别
s.SetLevel(Level);
try{
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(System.IO.Path.GetFileName(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);
}
return true;
}catch (Exception ex){
return false;
}finally{
s.Finish();
s.Close();
}
return true;
}
(2)实现代码
调用公共方法将文件批量压缩打包成压缩包并下载到服务器,从服务器读取压缩包下载至本地。
List<string> paths=new List<string>(){
"1.txt","2.txt"
};
string strSavePath=Server.MapPath("/");
foreach(var path in paths){
path=strSavePath+path;
}
string rarName="test.rar";
//调用公共方法
ZipFileMain(paths, strSavePath + rarName, 1);
//下载压缩包至本地
string strServerRarPath = strSavePath + rarName;
//文件不存在重新创建
if (!File.Exists(strServerRarPath)){
File.Create(strServerRarPath);
}
byte[] bytes = File.ReadAllBytes(strServerRarPath);
//通知浏览器下载文件而不是打开
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("Content-Disposition",
"attachment;filename="+HttpUtility.UrlEncode(strRarName, System.Text.Encoding.UTF8));
context.Response.BinaryWrite(bytes);
context.Response.Flush();
2、将服务器文件打包下载至本地(压缩包缓存到内存下载)
(1)将文件流压缩返回压缩后的流(公共方法)
/// <summary>
/// 将多个流进行zip压缩,返回压缩后的流.
/// </summary>
/// <param name="streams">key:文件名;value:文件名对应的要压缩的流.</param>
/// <returns>压缩后的流.</returns>
static MemoryStream PackageManyZip(Dictionary<string, Stream> streams){
byte[] buffer = new byte[6500];
MemoryStream returnStream = new MemoryStream();
var zipMs = new MemoryStream();
using (ZipOutputStream zipStream = new ZipOutputStream(zipMs)){
zipStream.SetLevel(9);
foreach (var kv in streams){
string fileName = kv.Key;
using (var streamInput = kv.Value){
zipStream.PutNextEntry(new ZipEntry(fileName));
while (true){
var readCount = streamInput.Read(buffer, 0, buffer.Length);
if (readCount > 0) zipStream.Write(buffer, 0, readCount);
else break;
}
zipStream.Flush();
}
}
zipStream.Finish();
zipMs.Position = 0;
zipMs.CopyTo(returnStream, 5600);
}
returnStream.Position = 0;
return returnStream;
}
(2)实现代码
将服务器的批量文件以流的形式压缩成一个压缩包流,再将压缩包流下载至本地。
List<string> paths=new List<string>(){
"1.txt","2.txt"
};
string strSavePath=Server.MapPath("/");
Dictionary<string, Stream> streamDic = new Dictionary<string, Stream>();
//文件转化成流
foreach(var path in paths){
string FileName = path;
path=strSavePath+path;
//文件不存在
if (!File.Exists(path)) continue;
//处理文件数据
Stream streamWriter = File.Open(path, FileMode.Open);
if(streamDic.ContainsKey(FileName)==false){//文件不重名
streamDic.Add(FileName, streamWriter);
}
}
//压缩
MemoryStream ms = new MemoryStream();
ms = PackageManyZip(streamDic);
byte[] bytes = new byte[(int)ms.Length];
ms.Read(bytes, 0, bytes.Length);
ms.Close();
//通知浏览器下载文件而不是打开
string zipName = DateTime.Today.ToString("yyyy-MM-dd") + ".zip";
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition",
"attachment;filename=" + HttpUtility.UrlEncode(zipName, System.Text.Encoding.UTF8));
Response.BinaryWrite(bytes);
Response.Flush();
注:streamDic添加数据时,需要先判断key是否存在,如果key在streamDic中已经存在,在Add相同的key会出现异常导致程序终止运行。