要求:文件是存储在腾讯云的COS上的,现在需要批量下载,并打包成一个zip的压缩包。
原理:使用HttpWebRequest把网络文件流放在内存中,ZipOutputStream进行打包成zip,需要注意的是打包在内存中进行,防止内存溢出。
首先NuGet安装SharpZipLib包(ICSharpCode.SharpZipLib.Zip.dll)。
贴代码:
using ICSharpCode.SharpZipLib.Zip; using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Web; namespace MyTest { class Program { static void Main(string[] args) { // http 网络文件地址 List<string> urls = new List<string>(); var ms = DownloadFileByHttpUrl(urls); //保存到本地,主要是为了看下是否打包成功 string zipName = "a.zip"; SaveFile(ms, zipName); Console.ReadKey(); } /// <summary> /// 批量下载,把http文件打包成zip压缩包流 /// </summary> /// <param name="HttpUrlList"></param> /// <returns></returns> public static MemoryStream DownloadFileByHttpUrl(List<string> HttpUrlList) { if (HttpUrlList == null || HttpUrlList.Count == 0) { return null; } try { var random = new Random(); var zipMs = new MemoryStream(); ZipOutputStream zipStream = new ZipOutputStream(zipMs); zipStream.SetLevel(9);//压缩率0~9 foreach (var url in HttpUrlList) { if (!string.IsNullOrWhiteSpace(url)) { var urlStr = HttpUtility.UrlDecode(url); string fileExt = Path.GetExtension(urlStr).ToLower(); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(urlStr); var strName = fileNameWithoutExtension.Substring(fileNameWithoutExtension.LastIndexOf("/") + 1) + random.Next(1000, 9999) + fileExt; zipStream.PutNextEntry(new ZipEntry(strName)); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlStr); request.AllowAutoRedirect = true; WebProxy proxy = new WebProxy(); proxy.BypassProxyOnLocal = true; proxy.UseDefaultCredentials = true; request.Proxy = proxy; WebResponse response = request.GetResponse(); using (Stream stream = response.GetResponseStream()) { Byte[] buffer = new Byte[1024]; int current = 0; while ((current = stream.Read(buffer, 0, buffer.Length)) != 0) { zipStream.Write(buffer, 0, current); } zipStream.Flush(); } } } zipStream.Finish(); zipMs.Position = 0; return zipMs; } catch (Exception ex) { throw ex; } } /// <summary> /// 保存文件到本地 /// </summary> /// <param name="stream"></param> /// <param name="file_name"></param> private static void SaveFile(MemoryStream stream, string file_name) { try { byte[] srcBuf = new Byte[stream.Length]; stream.Read(srcBuf, 0, srcBuf.Length); stream.Seek(0, SeekOrigin.Begin); string filePath = "D:\\FileZip"; if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } using (FileStream fs = new FileStream(filePath + "\\" + file_name, FileMode.Create, FileAccess.Write)) { fs.Write(srcBuf, 0, srcBuf.Length); fs.Close(); } } catch (Exception ex) { throw ex; } } } }