Domanda

Ho riversato la descrizione del formato e il codice sorgente per il formato di archivio 7z, ma ho ancora problemi a scrivere un contenitore valido. Presumo di poter creare un contenitore vuoto ... comunque ecco il mio inizio:

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

Penso che il mio problema principale sia la mancanza di comprensione di std :: ofstream :: write (). Il byte è un "carattere senza segno", amplificatore UInt64 &; UInt32 sono entrambi "unsigned long".

AGGIORNAMENTO0 : come tutti sottolineano, sarebbe un problema se lo eseguissi su una macchina big-endian. Questo non è il caso qui. Per Fredrik Janssen, dovrei indicare l'indirizzo dei non array. Vorrei anche ricordare che CrcCalc () è una funzione nell'SDK LZMA. Aggiunta di & Amp; aiuta un po ', è quel primo carattere senza segno [6] che sta avendo dei problemi.

AGGIORNAMENTO1 : codice di lavoro per ottenere un file di archivio vuoto di seguito.

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 () provengono dall'SDK LZMA.

È stato utile?

Soluzione

non conosco il formato di 7z, ma noto quando annoti offset, dimensione e crc che questi saranno scritti nel file in formato little-endian (suppongo che tu abbia una CPU little-endian).

Modifica: Probabilmente peggio, ti manca l'amplificatore &; prima di major, minor, offset, size e crc, ovvero stai lanciando i valori effettivi su un puntatore.

Altri suggerimenti

Uh ... Sono confuso. Ha un SDK ... che menzioni nel tuo post ... anche il Le fonti a 7 zip sono online . vedi anche p7zip su SourceForge. Ho appena dato un'occhiata ai sorgenti di p7zip e ci sono un sacco di file che iniziano con & Quot; 7z & Quot; sembra che farebbero il trucco.

Non ho usato il formato 7z programmaticamente da solo (solo tramite la riga di comando util / GUI) ma perché dovresti gestire tu stesso quelle cose di basso livello piuttosto che attraverso l'SDK? (diverso da quello della licenza LGPL)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top