C#利用ICSharpCode将远程文件打包并下载
应用于ASP.NET MVC中
方法主体代码:
public void GetFilesByOrder(string Order_ID, string IntNumber) { MemoryStream ms = new MemoryStream(); byte[] buffer = null; List<MaterialInfo> mList = mBll.SelectEntitys(m => m.Owner_ID == Order_ID); using (ZipFile file = ZipFile.Create(ms)) { file.BeginUpdate(); foreach (var item in mList) { UrlDataSource data = new UrlDataSource(CommonData.ApiFilePathBase + "Order/" + item.SaveName); file.Add(data, item.Name); } file.CommitUpdate(); buffer = new byte[ms.Length]; ms.Position = 0; ms.Read(buffer, 0, buffer.Length); } Response.AddHeader("content-disposition", "attachment;filename=" + IntNumber + ".zip"); Response.BinaryWrite(buffer); Response.Flush(); Response.End(); }
此处关键点有:
1.我不想在本地保存压缩包之后再下载,所以“ZipFile.Create(ms)”直接创建到内存里面
2.我的文件不是在本地的,在远程服务器上,所以“file.Add”不能直接添加路径,需要实现IStaticDataSource接口
对IStaticDataSource的实现:
public class UrlDataSource : IStaticDataSource { public string Url { get; set; } public UrlDataSource(string url) { this.Url = url; } public Stream GetSource() { return GetStreamUrl(); } public Stream GetStreamUrl() { try { WebRequest req = WebRequest.Create(Url); WebResponse result = req.GetResponse(); MemoryStream ms = new MemoryStream(); result.GetResponseStream().CopyTo(ms); ms.Position = 0; return ms; } catch { } return null; } }
实际做的时候调试了很多次,都是下载下来的压缩包里面的文件是空的,最后才发现一个非常容易忽略的问题,就是在把文件流保存到内存里面后没有把位置设为0“ms.Position = 0;”,此时的位置是文件流的末尾,所以保存下来的文件是空的,解决这个问题后,就顺利实现了打包下载。