13 Stimmen

Leitungslesedrosseln an 0x1A

Ich habe die folgende Datei:

abcde
kwakwa
<0x1A>
line3
linllll

Wo <0x1A> steht für ein Byte mit dem Hex-Wert 0x1A. Wenn Sie versuchen, diese Datei in Python zu lesen als:

for line in open('t.txt'):
    print line,

Er liest nur die ersten beiden Zeilen und verlässt die Schleife.

Die Lösung scheint zu sein, die Datei im Binärmodus (oder universellen Zeilenumbruchmodus) zu öffnen - "rb" oder "rU". Können Sie dieses Verhalten erklären?

28voto

Ned Batchelder Punkte 342778

0x1A ist Ctrl-Z, und DOS hat dies in der Vergangenheit als Markierung für das Dateiende verwendet. Versuchen Sie zum Beispiel, eine Eingabeaufforderung zu verwenden und Ihre Datei "einzutippen". Es wird nur der Inhalt bis zum Ctrl-Z angezeigt.

Python verwendet die Windows-CRT-Funktion _wfopen, die die Semantik "Ctrl-Z ist EOF" implementiert.

9voto

Mark Ransom Punkte 283960

Ned ist natürlich richtig.

Wenn Ihre Neugier etwas tiefer geht, ist die Ursache die Abwärtskompatibilität, die auf die Spitze getrieben wird. Windows ist mit DOS kompatibel, das die Tastenkombination Strg-Z als optionale Endmarkierung für Textdateien verwendete. Was Sie vielleicht nicht wissen, ist, dass DOS mit CP/M kompatibel war, das auf kleinen Computern vor dem PC sehr beliebt war. Das Dateisystem von CP/M speicherte die Dateigrößen nicht auf Byte-Ebene, sondern nur nach der Anzahl der Sektoren auf der Diskette. Wenn Ihre Datei nicht ein exaktes Vielfaches von 128 Byte war, brauchten Sie eine Möglichkeit, das Ende des Textes zu markieren. Dieser Wikipedia-Artikel deutet darauf hin, dass die Auswahl von Ctrl-Z auf einer noch älteren, von DEC verwendeten Konvention beruht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X