6.4 Das Dateiobjekt erzeugen
Wie aus den vorangegangenen Beispielen ersichtlich wurde, kann ein Dateiobjekt über die Built-in Function open erzeugt werden. Dieser Funktion können neben dem Dateinamen und dem Modus noch weitere Parameter übergeben werden, auf die sich ein Blick lohnt. Außerdem gibt es neben den bereits gezeigten Modi "r" und "w" noch einige weitere, die im Folgenden besprochen werden. Zum Schluss geben wir Ihnen noch einen Überblick über die Methoden des resultierenden Dateiobjekts.
6.4.1 open(filename, [mode, buffering, encoding, errors, newline])
Die Built-in Function open öffnet eine Datei und gibt das erzeugte Dateiobjekt zurück. Mithilfe dieses Dateiobjekts können Sie nachher die gewünschten Operationen auf der Datei durchführen.
Die ersten beiden Parameter haben wir in den vorangegangenen Abschnitten bereits besprochen. Dabei handelt es sich um den Dateinamen bzw. den Pfad zur zu öffnenden Datei und um den Modus, in dem die Datei zu öffnen ist. Für den Parameter mode muss ein String übergeben werden, wobei alle gültigen Werte und ihre Bedeutung in Tabelle 6.1 aufgelistet sind:
Modus | Beschreibung |
---|---|
"r" | Die Datei wird ausschließlich zum Lesen geöffnet. |
"w" | Die Datei wird ausschließlich zum Schreiben geöffnet. Eine eventuell bestehende Datei gleichen Namens wird überschrieben. |
"a" | Die Datei wird ausschließlich zum Schreiben geöffnet. Eine eventuell bestehende Datei gleichen Namens wird nicht überschrieben, sondern erweitert. |
"x" | Die Datei wird ausschließlich zum Schreiben geöffnet, sofern sie nicht bereits existiert. Wenn bereits eine Datei gleichen Namens vorhanden ist, wird eine FileExistsError-Exception geworfen. |
"r+", "w+", "a+", "x+" | Die Datei wird zum Lesen und Schreiben geöffnet. Beachten Sie, dass "w+" eine eventuell bestehende Datei gleichen Namens leert. |
"rb", "wb", "ab", "xb", "r+b", "w+b", "a+b", "x+b" | Die Datei wird im Binärmodus geöffnet. Beachten Sie, dass in diesem Fall bytes-Instanzen anstelle von Strings verwendet werden müssen. |
Der Parameter mode ist optional und wird als "r" angenommen, wenn er weggelassen wird.
Über den vierten, optionalen Parameter encoding kann das Encoding[ 18 ](Das Encoding legt fest, wie Sonderzeichen, die über den ASCII-Zeichensatz hinausgehen, abgespeichert werden. Näheres zu Encodings in Python erfahren Sie im Zusammenhang mit Strings in Abschnitt 13.4.4, »Zeichensätze und Sonderzeichen«. Dort finden Sie auch nähere Informationen zu den Parametern encoding und errors. ) festgelegt werden, in dem die Datei gelesen bzw. geschrieben werden soll. Die Angabe eines Encodings ergibt beim Öffnen einer Datei im Binärmodus keinen Sinn und sollte in diesem Fall weggelassen werden. Der fünfte Parameter errors bestimmt, wie mit Fehlern bei der Codierung von Zeichen im angegebenen Encoding verfahren werden soll. Wird für errors der Wert "ignore" übergeben, werden di26ese ignoriert. Bei einem Wert von "strict" wird eine ValueError-Exception geworfen, was auch das Verhalten ist, wenn der Parameter nicht angegeben wird.
Der Parameter buffering steuert die interne Puffergröße, und newline legt die Zeichen fest, die beim Lesen oder Schreiben der Datei als Newline-Zeichen erkannt bzw. verwendet werden sollen.
6.4.2 Attribute und Methoden eines Dateiobjekts
Die beim Öffnen angegebenen Parameter können über die Attribute name, encoding, errors, mode und newlines des resultierenden Dateiobjekts wieder gelesen werden.
Tabelle 6.2 fasst die wichtigsten Methoden eines Dateiobjekts kurz zusammen. Auf die Methoden seek und tell werden wir im folgenden Abschnitt noch einmal detaillierter eingehen.
6.4.3 Die Schreib-/Leseposition verändern
Die bisherigen Beispiele haben gezeigt, wie Dateien in einer sequenziellen Art und Weise gelesen bzw. geschrieben werden können. Aufgrund der speziellen Natur von Dateien ist es möglich, die Schreib- bzw. Leseposition beliebig zu verändern. Dazu existieren die Methoden seek und tell des Dateiobjekts.
seek(offset, [whence])
Die Methode seek eines Dateiobjekts setzt die Schreib-/Leseposition innerhalb der Datei. Sie ist das Gegenstück zur Methode tell, die die aktuelle Schreib-/Leseposition zurückgibt.
[»] Hinweis
Die Methode seek hat im Modus "a" keine Wirkung. Im Modus "a+" wird die Schreib-/Leseposition verändert, sodass an beliebigen Stellen in der Datei gelesen werden kann, vor einer Schreiboperation wird sie aber zurückgesetzt.
Sollte die Datei im Binärmodus geöffnet worden sein, wird der Parameter offset in Bytes vom Dateianfang aus gezählt. Diese Interpretation von offset lässt sich durch den optionalen Parameter whence beeinflussen (siehe Tabelle 6.3).
Wert von whence | Interpretation von offset |
---|---|
0 | Anzahl Bytes relativ zum Dateianfang |
1 | Anzahl Bytes relativ zur aktuellen Schreib-/Leseposition |
2 | Anzahl Bytes relativ zum Dateiende |
Sie können seek nicht so unbeschwert verwenden, wenn die Datei im Textmodus geöffnet wurde. Hier sollten als offset nur Rückgabewerte der Methode tell verwendet werden. Abweichende Werte können zu undefiniertem Verhalten führen.
Im folgenden Beispiel wird die Methode seek verwendet, um Breite, Höhe und Farbtiefe einer Bitmap-Grafik[ 19 ](Das Windows-Bitmap-Dateiformat (Endung .bmp) ist ein weitverbreitetes Rastergrafikformat. ) zu bestimmen.
def bytes2int(b):
res = 0
for x in b[::-1]:
res = (res << 8) + x
return res
f = open("bild.bmp", "rb")
f.seek(18)
print("Breite:", bytes2int(f.read(4)), "px")
print("Höhe:", bytes2int(f.read(4)), "px")
f.seek(2, 1)
print("Farbtiefe:", bytes2int(f.read(2)), "bpp")
f.close()
Der Spezifikation des Bitmap-Dateiformats[ 20 ](Diese finden Sie zum Beispiel in der Wikipedia unter: http://de.wikipedia.org/wiki/Windows_Bitmap) kann man entnehmen, dass sich die gesuchten Informationen an den Offsets 18, 22 und 28 befinden, jeweils in Form von 4- bzw. 2-Byte-Werten. Wir öffnen daher die Datei bild.bmp zum Lesen im Binärmodus und überspringen mithilfe der Methode seek die ersten 18 Bytes. An dieser Stelle können wir Breite und Höhe der Grafik auslesen und ausgeben.[ 21 ](Sollte bei Ihnen eine negative Höhe ausgegeben werden, ist dies kein Fehler im Programm, sondern eine Eigenart des Bitmap-Dateiformats: Eine negative Höheninformation bedeutet, dass die Bilddaten von oben nach unten gespeichert sind und nicht, wie üblich, von unten nach oben. )
Von der aktuellen Leseposition aus überspringen wir zwei weitere Bytes (der Parameter whence ist beim seek-Aufruf auf 1 gesetzt) und können zwei Bytes auslesen, die die Farbtiefe des Bildes enthalten.[ 22 ](Die Farbtiefe wird in »Bits per Pixel« (BPP) angegeben. )
Die mittels read eingelesenen Werte werden als bytes-String zurückgegeben und müssen daher noch mithilfe von bytes2int in ganze Zahlen konvertiert werden. Die Funktion bytes2int durchläuft den übergebenen bytes-String rückwärts, also mit dem höchstwertigen Byte zuerst. Das aktuelle Zwischenergebnis wird immer binär um acht Stellen nach links geschoben und dann das nächstniedere Byte aufaddiert.