public void VirDownload(List <E_SourceFile> sourceList) { fileList = sourceList; //文件个数以及大小校验 if (fileList.Count == 0) { ExitError("文件不存在"); return; } if (fileList.Sum(s => (long)s.FileSize) > int.MaxValue) { ExitError("文件过大,请减少文件个数后下载"); return; } try { ProcessSoftList(); //根据资料集合构建 E_VirtualZipStruct zipStruct = BuildZipStruct(); //发送文件 SendFile(zipStruct); } catch (OutOfMemoryException) { float a = GetFreeMemory(0); Util.SaveLog(_config.LogPath, $"当前内存不足,剩余内存为:{GetFreeMemory()}MB(排除了保留内存{_config.ReseverMemory / 1024 / 1024}GB)"); ExitError("服务器忙...请稍后再试"); return; } catch (Exception ex) { Util.SaveLog(_config.LogPath, ex.StackTrace.ToString()); ExitError("服务器异常,请稍后重试"); return; } }
/// <summary> /// 发送文件 /// </summary> /// <param name="zipStruct">Zip结构</param> private void SendFile(E_VirtualZipStruct zipStruct) { //设定默认字节流 uint DefaultBuffer = 256 * 1024; //已经读取的文件流长度 uint readOffset = 0; //缓冲区位移,用于判断是否该写入 uint bfrOffset = 0; string saveFileName = string.Format("打包下载{0}等{1}个文件.zip", fileList[0].FileName, fileList.Count); context.Response.ContentType = "application/octet-stream"; context.Response.AddHeader("Content-Disposition", "attachement;filename=" + HttpUtility.UrlEncode(saveFileName)); context.Response.AddHeader("Content-Length", zipStruct.ZipFileSize.ToString()); context.Response.AddHeader("Connection", "Keep-Alive"); //重置写入文件的Buffer大小(用于重置小于1M的文件大小) byte[] bfrByte = ResetBuffer(ref readOffset, zipStruct.ZipFileSize, DefaultBuffer); #region 文件读取 //1.读取zipXml中的data区域 foreach (var item in zipStruct.Header) { //1-1.读取头部区域的头部字节部分 { //读取配置中的头部字节 byte[] headerByte = item.Item1; //定义头部字节读取时的偏移量 ReadAndWrite(zipStruct.ZipFileSize, DefaultBuffer, ref readOffset, ref bfrOffset, ref bfrByte, headerByte); } //1-2.读取头部区域的文件流 { string path = item.Item2; ReadAndWrite(zipStruct.ZipFileSize, DefaultBuffer, ref readOffset, ref bfrOffset, ref bfrByte, path); } } //2.读取zipXML中的DIR区域 { byte[] DirByte = zipStruct.Dir.ToArray(); ReadAndWrite(zipStruct.ZipFileSize, DefaultBuffer, ref readOffset, ref bfrOffset, ref bfrByte, DirByte); } //3.读取zipXML中的End区域 { byte[] EndByte = zipStruct.End.ToArray(); ReadAndWrite(zipStruct.ZipFileSize, DefaultBuffer, ref readOffset, ref bfrOffset, ref bfrByte, EndByte); } context.Response.Close(); context.Response.End(); #endregion }
/// <summary> /// 构建Zip结构 /// </summary> /// <returns></returns> private E_VirtualZipStruct BuildZipStruct() { E_VirtualZipStruct zipStruct = new E_VirtualZipStruct(); //定义头部和目录的集合(用于计算目录偏移量) List <E_FileAndDir> fdList = new List <E_FileAndDir>(); //合计文件大小 long totalFileSize = 0; //虚拟压缩包总大小(包含文件大小和头部,目录,尾部区域的字节) long virtualZipSize = 0; foreach (var file in fileList) { //1.构造头部区域 E_LocalFileHeader header = FileHeaderInstance(file); zipStruct.Header.Add(new Tuple <byte[], string>(header.GetAllBytes(), file.PhyFilePath)); virtualZipSize += header.GetAllBytes().Count(); //2.构造目录部分 E_CentralDirFileHeader dir = CentralDirInstance(file); //计算dir的偏移量 if (fdList.Count > 0) { dir.HeaderOffset = GetClassSize(fdList.Select(s => s.Header).ToList(), (int)totalFileSize); } zipStruct.Dir.AddRange(dir.GetAllBytes()); //向头部和目录集合添加记录 fdList.Add(new E_FileAndDir() { Header = header, Dir = dir }); totalFileSize += file.FileSize; } E_EndCentralDirRecord endDir = EndDirInstance(fdList, (int)totalFileSize); zipStruct.End.AddRange(endDir.GetAllBytes()); virtualZipSize += zipStruct.Dir.Count(); virtualZipSize += zipStruct.End.Count(); virtualZipSize += totalFileSize; zipStruct.ZipFileSize = (uint)virtualZipSize; return(zipStruct); }
public void VirDownload(IList <E_SourceFile> sourceList) { fileList = sourceList; //文件个数以及大小校验 if (fileList.Count == 0) { ExitError("文件不存在"); return; } if (fileList.Sum(s => (long)s.FileSize) > int.MaxValue) { ExitError("文件过大,请减少文件个数后下载"); return; } //处理资料文件地址,文件名等 try { ProcessSoftList(); } catch (OutOfMemoryException) { float a = GetFreeMemory(0); ExitError("服务器忙...请稍后再试"); return; } catch (Exception ex) { try { Util.SaveLog(_config.ErrorLogSavePath, ex.StackTrace.ToString()); } catch { } ExitError("服务器异常,请稍后重试"); return; } //根据资料集合构建 E_VirtualZipStruct zipStruct = BuildZipStruct(); //发送文件 SendFile(zipStruct); }