Ganze Zahlen in Dateien Schreiben in Programmiersprachen c, Perl usw.

Für jeden numerischen Datentyp gibt es eine bestimmte Bytefolge, in c wie in Perl

Ganze Zahlen sind Integer und haben einen bestimmten Speicherbedarf. Darüber hinaus können diese Zahlen positiv oder negativ, also vorzeichenbehaftet sein. Letzeres verschiebt den möglichen Wertebereich: Auf einem Byte (8 Bit) ist es möglich 256 verschiedene Zahlen abzubilden, egal ob mit oder ohne Vorzeichen, die Anzahl möglicher Zahlen ändert sich nicht. Ohne Vorzeichen geht der Wertebereich von 0..255, mit Vorzeichen von -128..127.

Nun wird eine Zahl wie -127 nicht so in eine Datei geschrieben, denn so wie sie gerade aussieht, ist -127 eine Zeichenkette die 4 Bytes benötigen würde. Für die Zahl selbst jedoch genügt 1 Byte und daher gibt es in jeder Programmiersprache den numerischen Datentypen entsprechende Bytesequenzen. Die größte mögliche Ganzzahl auf einer 32-Bit-Architektur ist 4294967295 (vorzeichenlos) und diese Zahl benötigt genau 4 Byte in einer Bytesequenz.

Solche Vereinbarungen sind nicht nur der Typisierung schlechthin geschuldet sondern haben auch einen anderen Grund: Dateien werden blockweise gelesen, d.h., für eine bestimmte zu lesende Zahl muss die Anzahl der Blöcke und deren Größe von vornherein feststehen, denn sonst wäre es nicht möglich, Zahlen aus Dateien heraus wiederherzustellen. Untenstehendes Beispiel zeigt, wie 3 Blöcke mit der Länge von je 4 Byte aus dem FileHandle gelesen werden:

#include <stdint.h>

uint32_t offset[3];
fread( offset, sizeof(uint32_t), 3, fh );
               ^ 4 Bytes

Im Ergebnis dessen befinden sich 3 ganze Zahlen vom Type Unsigned Integer im Array mit dem Namen offset wobei jede einzelne Zahl einen Wert von 0..4294967295 annehmen kann. Genauso wie Blöcke aus einer Datei zu lesen sind, werden sie mit fwrite() auch geschrieben, Sytax ist identisch.

Übersicht der numerischen Datentypen der c-Library stdint.h

Datentype Wertebereich Speicherbedarf Byteorder Schablone
int8_t -128..127 1 Byte - c
uint8_t 0..255 1 Byte - C
int16_t -32,768 to 32,767 2 Bytes Little Endian s
uint16_t 0..65535 2 Bytes Little Endian v
int32_t -2,147,483,648 to 2,147,483,647 4 Bytes Little Endian l
uint32_t 0..0xFFFFFFFF 4 Bytes Little Endian V

Perl, pack() und unpack()

Die Perlfunktion pack() erzeugt der Schablone bzw. dem Datentype entsprechend die richtige Bytesequenz, Beispiele:

# 4 Bytes als Little Endian
# unsigned integer
$binary = pack "V", 0x1AF3;

# 12 Bytes für 3 vorzeichenlose Ganzzahlen
# Little Endian (Vax-Order)
$binary = pack "VVV", 1, 2, 3;

Umgekehrt stellt unpack() aus einer Bytesequenz entsprechend der Schabloe die richtigen Datentypen wieder her:

# lese 12 Bytes aus FileHandle $fh
read( $fh, $buffer, 12);

# stelle 3 Zahlen unsigned integer wieder her
($ent, $att, $val) = unpack "V3", $buffer;

Datenschutzerklärung: Diese Seite dient rein privaten Zwecken. Auf den für diese Domäne installierten Seiten werden grundsätzlich keine personenbezogenen Daten erhoben. Das Loggen der Zugriffe mit Ihrer Remote Adresse erfolgt beim Provider soweit das technisch erforderlich ist. s​os­@rolf­rost.de.