c++ - 如何为 7z 存档格式写入二进制数据?

标签 c++ std 7zip ofstream

我一直在研究 7z 存档格式的格式描述和源代码,但我仍然无法编写有效的容器。我假设我可以创建一个空容器...无论如何这是我的开始:

std::ofstream ofs(archivename.c_str(), std::ios::binary|std::ios::trunc);

Byte signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
Byte major = 0;
Byte minor = 3;

ofs.write((const char*)signature, 6);
ofs.write((const char*)major, 1);
ofs.write((const char*)minor, 1);

UInt64 offset = 0;
UInt64 size = 0;
UInt32 crc = 0;

ofs.write((const char*)offset, 4);
ofs.write((const char*)size, 8);
ofs.write((const char*)crc, 8);
ofs.write((const char*)CrcCalc(0, 0), 8);

ofs.close();

我认为我的主要问题是缺乏对 std::ofstream::write() 的理解。 Byte 是一个“unsigned char”,UInt64 和 UInt32 都是“unsigned long”。

UPDATE0:正如每个人所指出的,如果我在大端机器上运行它就会有问题。这里不是这种情况。 Per Fredrik Janssen,我应该转换非数组的地址。我还应该提到 CrcCalc() 是 LZMA SDK 中的一个函数。添加 & 有点帮助,这是第一个 unsigned char[6] 有一些问题。

UPDATE1:获取下方空存档文件的工作代码。

static void SetUInt32(Byte *p, UInt32 d)
{
  for (int i = 0; i < 4; i++, d >>= 8)
    p[i] = (Byte)d;
}

static void SetUInt64(Byte *p, UInt64 d)
{
  for (int i = 0; i < 8; i++, d >>= 8)
    p[i] = (Byte)d;
}

void make_7z_archive()
{
  CrcGenerateTable();

  std::ofstream ofs(archivename.c_str(), std::ios::binary|std::ios::trunc);

  Byte signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
  Byte major = 0;
  Byte minor = 3;

  ofs.write((const char*)signature, 6);
  ofs.write((const char*)&major, 1);
  ofs.write((const char*)&minor, 1);

  UInt64 offset = 0;
  UInt64 size = 0;
  UInt32 crc = 0;

  Byte buf[24];
  SetUInt64(buf + 4, offset);
  SetUInt64(buf + 12, size);
  SetUInt32(buf + 20, crc);
  SetUInt32(buf, CrcCalc(buf + 4, 20));

  ofs.write((const char*)buf, 24);

  ofs.close();
}

注意:CrcGenerateTable() 和 CrcCalc() 来自 LZMA SDK。

最佳答案

不知道 7z 的格式,但我注意到当你写下偏移量、大小和 crc 时,这些将以小端格式写入文件(我假设你有一个小端 CPU)。

编辑:可能更糟的是,您在 major、minor、offset、size 和 crc 之前缺少 &,即您正在将实际值转换为指针。

关于c++ - 如何为 7z 存档格式写入二进制数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/496204/

相关文章:

java - Java 中的进程生成器

c++ - openGl reshape 功能

c++ - 进程 qmake.exe 退出并显示代码 2 - 第一次使用 Qt 和 Qt Creator

c++ - 为什么 std::thread 缺少基本功能?

c++ - 你如何在 XCode + C++ 中使用 std::vector?

c++ - 为什么 is_lock_free 是一个成员函数?

compression - 如何避免压缩 thumbs.db 文件

c++ - 如何使用 C++17 获取文件大小(以字节为单位)

c++ - 使用 C++ 模板或宏来生成编译时函数

java - Zip - 添加较新的文件和文件夹,删除旧的文件和文件夹