dedlfix: Binärdateien

Beitrag lesen

Hi!

Was ich nicht ganz verstehe:

Der Algorithmus umschreibt den Vorgang der Serialisierung und Deserialize. Am einfachsten sind Arrays zu serialisieren, Algorithmus Beispiel:
0 lege eine Schleife um jedes Array-Element, Schleifenkörper:
1 bestimme die Länge eines Elements
2 schreibe die Länge mit pack("N", $length) in die Sequenz (4 bytes)
3 schreibe die Bytes des Array-Elements in die Sequenz (x bytes)
<-- Loop
Sind in Deinem Array die Werte, die in die Binary sollen?
Was ist der Unteschied zw. 2 und 3?

Das mit dem Array hat anscheinend mehr verwirrt. Es geht im Grunde genommen darum, mehrere unterschiedlich lange Werte in der Datei abzulegen. Diese Werte müssen dabei nicht einem Array stehen, sie können auch einzeln dem Stream hinzugefügt werden. Da die Länge der Elemente variabel ist - wie es bei String der Fall ist, Zahlentypen haben in der Regel eine feste Länge - muss man für den Lesenden mitteilen, wie lang das nächste Element ist. Feste Feldgrößen wären eine Möglichkeit, da muss das Ende des Inhalts besonders gekennzeichnet werden, wenn er nicht die gesamte Länge ausfüllt. Dazu nimmt man das NUL. Feste Längen vergeuden aber Platz. Deswegen schreibt man effizienter: "Jetzt kommen x Byte" (2) und dann die x Bytes (3), "nun folgen y Bytes" (2) und die y Bytes (3). Bei einem Array läuft das im Gegensatz zu einzelnen Elementen in einer Schleife ab.

... klingt das so, als ob ich das mit get_file_contents() nicht so schlau mache. Klingt eher so, als wenn Du fread() mit einer bestimmten Länge anwenden möchtest. Wie kriegt man dann im Vorhinein die Länge raus?

Wenn das Format mit variablen Längen arbeitet, kann man das häppchenweise lesen. Nun kann man aber noch Performance-Überlegungen anstellen. Dateisystemzugriffe sind möglicherweise langsam (heutzutage vielleicht nicht mehr, weil eventuell ein Cache mitspielt). Jedenfalls wäre es dann besser, einen großen Block zu lesen, was vergleichsweise weniger aufwändig ist, als zwei halb so große Blöcke einzeln zu lesen. Diesen Block im Speicher kann man dann wieder häppchenweise auswerten. Man kann dazu Streams nehmen, die kümmern sich im Verborgenen um das eigentliche Lesen vom Medium, puffern das und liefern genau die gewünschten Häppchen aus dem Puffer, wenn man einzelne kleine Lesezugriffe darauf absetzt.

PHP kennt zwar auch Streams, die arbeiten jedoch nicht in Richtung Dateisystem sondern vermitteln zwischen herkömmlichen Dateisystemfunktionen und diversen externen Ressourcen. Für das Lesen von Binärdateien kann man also nur (wenn ich nichts übersehen habe) entweder fread()-Häppchen lesen oder mit file_get_contents() im Ganzen und dann den als Puffer verwendeten String häppchenweise abklappern. Soweit zur Theorie. In deinem Fall mit den Zahlenwerten mit fester Länge bringt ein häppchenweises Lesen kaum Vorteile. Vielmehr kann man unpack() den ganzen Batzen übergeben, der kann mit V* (oder so ähnlich) die Auftrennung sehr gut selbständig vornehmen.

Lo!