Random-Access und UTF-8

English

Es ist eine schöne Sache, dass man „Random-Access-Dateien“ verwenden kann und die Möglichkeit hat, effizient zu einer beliebigen Byteposition zu springen, um ab dort zu lesen oder zu schreiben.

Das gilt auch für Textdateien, bei denen pro Zeichen eine feste Anzahl Bytes verwendet wird, z.B. immer genau ein Byte oder immer genau zwei Bytes pro Zeichen.

Nun ist aber der neue Standard für Text-Dateien UTF-8. Da funktioniert das auch fast so, weil bei vielen Sprachen die Zeichen immer noch meistens ein Byte groß sind.
Aber wenn man zu einer bestimmten Byte-Position springt, kann es passieren, dass man mitten zwischen den Bytes eines Zeichens („Code Point“) landet und nicht am Anfang eines Zeichens. Woher soll man das erkennen, wenn man nicht den Effizienzgewinn von Random-Access wegwirft und die Datei Byte für Byte und Zeichen für Zeichen liest, bis man an der betreffenden Stelle ist?
Nun lässt sich das aber finden, da UTF-8 Self-synchronizing ist. Man weiss, dass das erste Byte einer Bytesequenz, die ein Zeichen beschreibt, entweder mit 11 oder mit 0 anfängt. Alle weiteren Bytes fangen mit 10 an. So lässt sich vorwärts oder rückwärts an den Anfang eines Zeichens springen, das zumindest so nahe wie möglich an der gewünschten Position beginnt.
Schwieriger wird es, wenn man nicht an eine bestimmte Byte-Position, sondern an eine bestimmte Zeichenposition springen will.
Man kann das zwar schätzen, aber man weiß nie genau, wie lang die Zeichen in dem übersprungenen Bereich als Bytesequenz sind. Das lässt sich mit einer Indexstruktur in einer zweiten Datei oder in einem dafür abgestellten Bereich der Datei lösen, wo vermerkt ist, an welcher Byteposition man jeweils den Beginn von Zeichen k*b findet, wobei b eine „Blockgröße“, z.B. 1024 Zeichen, ist. Solange man nur hinten anhängt und nicht mitten in der Datei etwas überschreibt, sollte das möglich sein.

Share Button

Beteilige dich an der Unterhaltung

1 Kommentar

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*