internal void WriteDir(IFormatterX writer) { Signature = ZipConstants.ZipDirEntrySignature; // 写入头部 writer.Write(this); }
internal void Write(IFormatterX writer) { Signature = ZipConstants.ZipEntrySignature; // 取得数据流位置 RelativeOffsetOfLocalHeader = (UInt32)writer.Stream.Position; if (IsDirectory) { // 写入头部 writer.Write(this); return; } Int32 dsLen = (Int32)DataSource.Length; //if (dsLen <= 0) CompressionMethod = CompressionMethod.Stored; // 计算签名和大小 if (Crc == 0) { Crc = DataSource.GetCRC(); } if (UncompressedSize == 0) { UncompressedSize = (UInt32)dsLen; } if (CompressionMethod == CompressionMethod.Stored) { CompressedSize = UncompressedSize; } if (DataSource.IsCompressed) { CompressedSize = (UInt32)dsLen; } // 写入头部 writer.Write(this); // 没有数据,直接跳过 if (dsLen <= 0) { return; } #region 写入文件数据 // 数据源。只能用一次,因为GetData的时候把数据流移到了合适位置 var source = DataSource.GetData(); if (DataSource.IsCompressed) { // 可能数据源是曾经被压缩过了的,比如刚解压的实体 source.CopyTo(writer.Stream, 0, dsLen); return; } switch (CompressionMethod) { case CompressionMethod.Stored: // 原始数据流直接拷贝到目标。必须指定大小,否则可能读过界 source.CopyTo(writer.Stream, 0, dsLen); break; case CompressionMethod.Deflated: { // 记录数据流位置,待会用来计算已压缩大小 Int64 p = writer.Stream.Position; using (var stream = new DeflateStream(writer.Stream, CompressionMode.Compress, true)) { source.CopyTo(stream); stream.Close(); } CompressedSize = (UInt32)(writer.Stream.Position - p); // 回头重新修正压缩后大小CompressedSize p = writer.Stream.Position; // 计算好压缩大小字段所在位置 writer.Stream.Seek(RelativeOffsetOfLocalHeader + 18, SeekOrigin.Begin); //var wr = writer as IWriter2; //wr.Write(CompressedSize); writer.Write(CompressedSize); writer.Stream.Seek(p, SeekOrigin.Begin); } break; //case CompressionMethod.LZMA: // { // // 记录数据流位置,待会用来计算已压缩大小 // Int64 p = writer.Stream.Position; // source.CompressLzma(writer.Stream, 10); // CompressedSize = (UInt32)(writer.Stream.Position - p); // // 回头重新修正压缩后大小CompressedSize // p = writer.Stream.Position; // // 计算好压缩大小字段所在位置 // writer.Stream.Seek(RelativeOffsetOfLocalHeader + 18, SeekOrigin.Begin); // var wr = writer as IWriter2; // wr.Write(CompressedSize); // writer.Stream.Seek(p, SeekOrigin.Begin); // } // break; default: throw new XException("无法处理的压缩算法{0}!", CompressionMethod); } //#if DEBUG // if (ts != null) ts.UseConsole = true; //#endif #endregion }