ich das selbst von der Arbeit nach etwas herausgefunden. Die tar file spec sagt Ihnen eigentlich alles, was Sie wissen müssen.
Als Erstes beginnt jede Datei mit einem 512-Byte-Header, so dass Sie sie mit einem char [512] oder einem char * an einer beliebigen Stelle in Ihrem größeren char-Array darstellen können (wenn Sie die gesamte Datei in ein Array laden) beispielsweise).
Der Header sieht wie folgt aus:
location size field
0 100 File name
100 8 File mode
108 8 Owner's numeric user ID
116 8 Group's numeric user ID
124 12 File size in bytes
136 12 Last modification time in numeric Unix time format
148 8 Checksum for header block
156 1 Link indicator (file type)
157 100 Name of linked file
Also, wenn Sie den Dateinamen möchten, können Sie es gleich hier mit string filename(buffer[0], 100);
greifen. Der Dateiname ist null, daher können Sie eine Überprüfung durchführen, um sicherzustellen, dass mindestens eine Null vorhanden ist. Wenn Sie Speicherplatz sparen möchten, müssen Sie die Größe nicht beibehalten.
Jetzt wollen wir wissen, ob es eine Datei oder ein Ordner ist. Die „Verbindungsanzeige“ Feld hat diese Informationen, so:
// Note that we're comparing to ascii numbers, not ints
switch(buffer[156]){
case '0': // intentionally dropping through
case '\0':
// normal file
break;
case '1':
// hard link
break;
case '2':
// symbolic link
break;
case '3':
// device file/special file
break;
case '4':
// block device
break;
case '5':
// directory
break;
case '6':
// named pipe
break;
}
An dieser Stelle haben wir bereits alle Informationen, die wir über Verzeichnisse benötigen, aber wir brauchen noch eine Sache von normalen Dateien: die tatsächlichen Dateiinhalte.
Die Länge der Datei kann auf zwei verschiedene Arten gespeichert werden, entweder als Null-terminierte oktale Zeichenfolge mit 0 oder Leerzeichen oder als "Basis-256-Codierung", die durch Setzen des höherwertigen Bits angezeigt wird des linken Bytes eines numerischen Feldes ".
Numerische Werte werden in Oktalzahlen mit ASCII-Ziffern und führenden Nullen kodiert. Aus historischen Gründen sollte ein endgültiges NUL- oder Leerzeichen verwendet werden. Obwohl 12 Bytes zum Speichern der Dateigröße reserviert sind, können daher nur 11 Oktalstellen gespeichert werden.Dies ergibt eine maximale Dateigröße von 8 Gigabyte für archivierte Dateien. Um diese Einschränkung zu überwinden, führte Star im Jahr 2001 eine Basis-256-Kodierung ein, die durch Setzen des höherwertigen Bits des am weitesten links liegenden Bytes eines numerischen Feldes angezeigt wird. GNU-tar und BSD-tar folgten dieser Idee. Darüber hinaus packen die Versionen von tar vor dem ersten POSIX-Standard von 1988 die Werte mit Leerzeichen anstelle von Nullen.
Hier ist, wie Sie das Oktalformat lesen würde, aber ich habe keinen Code für die Basis-256-Version geschrieben:
// in one function
int size_of_file = octal_string_to_int(&buffer[124], 11);
// elsewhere
int octal_string_to_int(char *current_char, unsigned int size){
unsigned int output = 0;
while(size > 0){
output = output * 8 + *current_char - '0';
current_char++;
size--;
}
return output;
}
Ok, so haben wir jetzt alles außer den tatsächlichen Dateiinhalte. Alles, was wir tun müssen, ist das nächste size
Bytes von Daten aus der TAR-Datei packen und wir werden unseren Dateiinhalt haben:
// Get to the next block after the header ends
location += 512;
file_contents = new char[size];
memcpy(file_contents, &buffer[location], size);
// Go to the next block by rounding up to 512
// This isn't necessarily the most efficient way to do this,
// but it's the most obvious.
location += (int)ceil(size/512.0)
'man tar' sagt mir' -t Listet den Archivinhalt auf "stdout" auf. Ist das was du willst? – Potatoswatter
Was ich eigentlich will, ist das Gegenteil: eine TAR-Datei von der Standardeingabe lesen. –