Zip文件格式

标识头

50 4B 01 02 kCentralFileHeader

50 4B 03 04 kLocalFileHeader

50 4B 05 06 kEndOfCentralDir


kEndOfCentralDir:

文件最后位置, cdStartOffset 定位 kCentralFileHeader

struct CEcd
{
  UInt16 thisDiskNumber;
  UInt16 startCDDiskNumber;
  UInt16 numEntriesInCDOnThisDisk;
  UInt16 numEntriesInCD;
  UInt32 cdSize;
  UInt32 cdStartOffset;
  UInt16 commentSize;
  void Parse(const Byte *p);
};

void CEcd::Parse(const Byte *p)
{
  thisDiskNumber = Get16(p);
  startCDDiskNumber = Get16(p + 2);
  numEntriesInCDOnThisDisk = Get16(p + 4);
  numEntriesInCD = Get16(p + 6);
  cdSize = Get32(p + 8);
  cdStartOffset = Get32(p + 12);
  commentSize = Get16(p + 16);
}


kCentralFileHeader:

集中数据 压缩包内项目, LocalHeaderPosition  为实际数据偏移 kLocalFileHeader

<span style="font-family: Arial, Helvetica, sans-serif;">HRESULT CInArchive::ReadCdItem(CItemEx &item)</span>
{
  item.FromCentral = true;
  const int kBufSize = 42;
  Byte p[kBufSize];
  SafeReadBytes(p, kBufSize);
  item.MadeByVersion.Version = p[0];
  item.MadeByVersion.HostOS = p[1];
  item.ExtractVersion.Version = p[2];
  item.ExtractVersion.HostOS = p[3];
  item.Flags = Get16(p + 4);
  item.CompressionMethod = Get16(p + 6);
  item.Time = Get32(p + 8);
  item.FileCRC = Get32(p + 12);
  item.PackSize = Get32(p + 16);
  item.UnPackSize = Get32(p + 20);
  UInt16 headerNameSize = Get16(p + 24);
  UInt16 headerExtraSize = Get16(p + 26);
  UInt16 headerCommentSize = Get16(p + 28);
  UInt32 headerDiskNumberStart = Get16(p + 30);
  item.InternalAttributes = Get16(p + 32);
  item.ExternalAttributes = Get32(p + 34);
  item.LocalHeaderPosition = Get32(p + 38);
  ReadFileName(headerNameSize, item.Name);
  
  if (headerExtraSize > 0)
  {
    ReadExtra(headerExtraSize, item.CentralExtra, item.UnPackSize, item.PackSize,
        item.LocalHeaderPosition, headerDiskNumberStart);
  }

  if (headerDiskNumberStart != 0)
    throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
  
  // May be these strings must be deleted
  /*
  if (item.IsDir())
    item.UnPackSize = 0;
  */
  
  ReadBuffer(item.Comment, headerCommentSize);
  return S_OK;
}


kLocalFileHeader

数据后面紧跟项目压缩后的数据

HRESULT CInArchive::ReadLocalItem(CItemEx &item)
{
  const int kBufSize = 26;
  Byte p[kBufSize];
  SafeReadBytes(p, kBufSize);

  item.ExtractVersion.Version = p[0];
  item.ExtractVersion.HostOS = p[1];
  item.Flags = Get16(p + 2);
  item.CompressionMethod = Get16(p + 4);
  item.Time = Get32(p + 6);
  item.FileCRC = Get32(p + 10);
  item.PackSize = Get32(p + 14);
  item.UnPackSize = Get32(p + 18);
  UInt32 fileNameSize = Get16(p + 22);
  item.LocalExtraSize = Get16(p + 24);
  ReadFileName(fileNameSize, item.Name);
  item.FileHeaderWithNameSize = 4 + NFileHeader::kLocalBlockSize + fileNameSize;
  if (item.LocalExtraSize > 0)
  {
    UInt64 localHeaderOffset = 0;
    UInt32 diskStartNumber = 0;
    ReadExtra(item.LocalExtraSize, item.LocalExtra, item.UnPackSize, item.PackSize,
      localHeaderOffset, diskStartNumber);
  }
  /*
  if (item.IsDir())
    item.UnPackSize = 0;       // check It
  */
  return S_OK;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值