/// <summary> /// zip中央目录的实例化 /// </summary> /// <param name="file"></param> /// <returns></returns> private E_CentralDirFileHeader CentralDirInstance(E_SourceFile file) { E_CentralDirFileHeader c = new E_CentralDirFileHeader(); c.MadeVersion = BitConverter.GetBytes((short)0x003F); c.MinExtractVersion = BitConverter.GetBytes((short)0x000a); c.PurposeFlag = BitConverter.GetBytes((short)0x0800); //压缩方法默认0,文件修改时间和日期默认0 c.CRC32 = file.CRC32; c.CmpSize = BitConverter.GetBytes((int)file.FileSize); c.UnCmpSize = BitConverter.GetBytes((int)file.FileSize); c.FileNameLength = BitConverter.GetBytes((short)Encoding.UTF8.GetBytes(file.FileName).Length); //扩展域长度,文件注释长度,开始位置的磁盘编号,为0即可 c.ExternalFileAttr = BitConverter.GetBytes(0x00000020); //本地文件头的相对位移具体地方再做计算 c.FileName = Encoding.UTF8.GetBytes(file.FileName); //扩展域和文件注释内容为null即可 return(c); }
/// <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); }