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会出现异常导致程序终止运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值