Pergunta

Eu tenho derramando sobre a descrição do formato e código fonte para o formato de arquivo 7z, mas eu ainda estou tendo dificuldade para escrever um recipiente válido. Eu suponho eu posso criar um recipiente vazio ... de qualquer forma aqui está o meu começo:

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();

Eu acho que meu principal problema é a falta de compreensão de std :: ofstream :: write (). Byte é um 'char não assinado', UInt64 & UInt32 são ambos 'unsigned long'.

UPDATE0 : como todos os pontos fora, seria um problema se eu corri isso em uma máquina big-endian. Isso não é o caso aqui. Per Fredrik Janssen, eu deveria estar lançando o endereço dos não-matrizes. Gostaria também de mencionar que CrcCalc () é uma função no LZMA SDK. Adicionando & ajuda um pouco, é que o primeiro unsigned char [6] que está tendo alguns problemas.

Update1 :. Código de Trabalho para obter um arquivo vazio abaixo

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();
}

NOTA: CrcGenerateTable () e CrcCalc () são do LZMA SDK

.
Foi útil?

Solução

não sei o formato 7z, mas eu aviso quando você anote offset, tamanho e CRC que estes serão gravados no arquivo em little-endian formato (I supor que você tem uma CPU little-endian).

Edit:. Um provavelmente pior, você está faltando o & antes de maior, menor, offset, tamanho e CRC, ou seja, você está lançando os valores reais para um ponteiro

Outras dicas

Uh ... Estou confuso. Ele tem um SDK ... que você menciona no seu post ... também o 7-zip fontes são online. ver também p7zip no SourceForge. Eu só olhei para as fontes para p7zip e há um monte de arquivos que começam com "7z" que parecem que faria o truque.

Eu não usei o formato 7z programattically me (apenas através da linha de comando util / GUI) mas por que você precisa para lidar com essas coisas de baixo nível de si mesmo, em vez de através do SDK? (Que não por causa do licenciamento LGPL)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top