NB02_Lesen_und_Schreiben_von_Dateien¶
(c) 2025 Technische Hochschule Augsburg - Fakultät für Informatik - Prof.Dr.Nik Klever - Impressum
Builtin-Funktion open()¶
Die Builtin-Funktion open() wird im allgemeinen mit zwei Argumenten filename und mode aufgerufen. Dabei ist filename der Name der Datei, genauer gesagt, der Pfadname der Datei, die geöffnet werden soll. Und mode ist der Modus, d.h. ob die Datei lesend (mode=r) oder schreibend (mode=w, wenn die Datei neu erstellt wird bzw. überschrieben wird oder mode=a, wenn an die Datei angehängt wird) geöffnet werden soll. Der Rückgabewert dieser Funktion ist ein Dateiobjekt.
Schreiben einer Datei¶
Funktion open() zum Schreiben¶
Mit dem folgenden Ausdruck wird die Datei textdatei.txt zum Schreiben neu erstellt, bzw. wenn diese Datei bereits existiert, überschrieben:
wd = open("textdatei.txt","w")
Der Rückgabewert der Funktion open ist ein Dateiobjekt, welches in diesem Fall in der Variablen wd abgespeichert wird. Ein Dateiobjekt kann die Funktion write benutzen, um Zeichenketten in die Datei zu schreiben.
Funktion write()¶
Entsprechende andere Objekte, wie z.B. Integer- oder Float-Zahlen müssen erst mit der str-Funktion in eine Zeichenkette umgewandelt werden. Der Rückgabewert der Funktion write ist die Anzahl der Zeichen, die in die Datei geschrieben worden sind.
Wichtig: Unterschied zur Funktion print()¶
Wichtig zu wissen ist, dass bei der Funktion write() der Programmierer - im Gegensatz zur Funktion print() - selbst Zeilenumbrüche (mittels dem Zeilenumbruch-Zeichen "\n") an entsprechend geeigneten bzw. notwendigen Stellen anhängen muss! Dies kann über einen eigenen Aufruf write("\n") geschehen, aber auch über das Anhängen (oder Voranstellen) eines Zeilenumbruchs an die Zeichenkette +"\n".
a = """Dies ist ein mehrzeiliger Text
mit vier Zeilen ohne Zeilenende-Zeichen
und einfachen "Hochkommas" innerhalb der Zeichenkette,
die dann nicht maskiert werden müssen"""
wd.write(a)
163
wd.write("\n")
1
b = 87.467
wd.write("\n"+str(b)+"\n")
8
c = "Alternativ kann ein mehrzeiliger Text\nauch mit Zeilenende-Zeichen\nversehen werden, um\nein Zeilenende zu markieren"
wd.write(c)
113
Schliessen einer Datei - Funktion close()¶
Wenn alle Datensätze in die Datei geschrieben worden sind, dann muss die Datei mit der Funktion close geschlossen werden. Ansonsten könnte ein unkontrollierter Zustand bzw. auch Verlust der bisher geschriebenen Daten in die Datei geschehen.
wd.close()
Lesen einer Datei¶
Funktion open() zum Lesen¶
Mit dem folgenden Aufruf der Funktion open wird die Datei textdatei.txt zum Lesen geöffnet:
rd = open("textdatei.txt","r")
Funktion read()¶
Über die Funktion read() wird die gesamte Datei eingelesen und der Inhalt der Datei als Rückgabewert zurückgegeben - allerdings besitzt die Funktion read auch noch einen Parameter size, der als Argument übergeben werden kann und angibt, wieviele Bytes gelesen werden sollen. Wenn dieser Parameter nicht angegeben wird (oder negativ ist), dann wird die gesamte Datei eingelesen.
inhalt = rd.read()
print(inhalt)
Dies ist ein mehrzeiliger Text mit vier Zeilen ohne Zeilenende-Zeichen und einfachen "Hochkommas" innerhalb der Zeichenkette, die dann nicht maskiert werden müssen 87.467 Alternativ kann ein mehrzeiliger Text auch mit Zeilenende-Zeichen versehen werden, um ein Zeilenende zu markieren
Wenn alle erforderlichen Daten aus der Datei gelesen worden sind, dann sollte die Datei wieder mit der Funktion close geschlossen werden. Ansonsten könnte die Datei in einen unkontrollierten Zustand geraten, wobei die Leseoperation unkritischer als die Schreiboperation ist.
rd.close()
Funktion readline()¶
Anstelle der Funktion read() kann auch die Funktion readline() verwendet werden, die jeweils nur eine Zeile aus der Datei einliest:
rd = open("textdatei.txt","r")
zeile1 = rd.readline()
print(zeile1)
zeile2 = rd.readline()
print(zeile2)
rd.close()
Dies ist ein mehrzeiliger Text mit vier Zeilen ohne Zeilenende-Zeichen
Einlesen der gesamten Datei in einer Schleife¶
Um die gesamte Datei in einer Schleife einzulesen, ist der beste und effektivste Weg, direkt über das Dateiobjekt zu iterieren:
rd = open("textdatei.txt","r")
for zeile in rd:
print(zeile)
rd.close()
Dies ist ein mehrzeiliger Text mit vier Zeilen ohne Zeilenende-Zeichen und einfachen "Hochkommas" innerhalb der Zeichenkette, die dann nicht maskiert werden müssen 87.467 Alternativ kann ein mehrzeiliger Text auch mit Zeilenende-Zeichen versehen werden, um ein Zeilenende zu markieren
%%Mooc StringAssessment
Unterschied str - print
In dem folgenden Code wird die komplette Datei auf einmal eingelesen:
rd = open("textdatei.txt","r")
inhalt = rd.read()
print(inhalt)
rd.close()
In dem folgenden Code wird dagegen die komplette Datei Zeile für Zeile eingelesen:
rd = open("textdatei.txt","r")
for zeile in rd:
print(zeile)
rd.close()
Der Unterschied in der Ausgabe ist, das in der print-Funktion automatisch ein Zeilenumbruch angehängt wird
Hinweis:Schauen sie sich in der offiziellen Dokumentation (s. weitere Literatur) die möglichen Argumente der print-Funktion an
Geben sie als Antwort nur die veränderte Zeile mit der print-Funktion an!
Wie können sie nun die Ausgabe in dem zweiten Code so verändern, dass die Ausgabe identisch mit der ersten Ausgabe wird ?
Vermeidung von close() mit with¶
In Python gibt es ein besonderes Schlüsselwort with welches generell den Beginn eines bestimmten Kontextes definiert. Im Zusammenhang mit dem Schreiben und Lesen von Dateien ist dieser Kontext das Öffnen einer Datei. Der Vorteil ist, dass mit dem Schlüsselwort with und dem Öffnen der Datei dieser Kontext durch einen Block (d.h. durch die Einrückung) beginnt und der Kontext mit der Beendigung des Blocks (d.h. durch die Ausrückung) der endet und bei Beendigung des Kontexts die Datei automatisch geschlossen wird und damit der Zustand closed des Dateiobjekts entsprechend wahr wird.
with open("textdatei.txt") as rd:
inhalt = rd.read()
print(inhalt)
rd.closed
Dies ist ein mehrzeiliger Text mit vier Zeilen ohne Zeilenende-Zeichen und einfachen "Hochkommas" innerhalb der Zeichenkette, die dann nicht maskiert werden müssen 87.467 Alternativ kann ein mehrzeiliger Text auch mit Zeilenende-Zeichen versehen werden, um ein Zeilenende zu markieren
True
%%Mooc StringAssessment
with
Welches Ergebnis wird angezeigt, wenn die folgenden Statements ausgeführt werden:
with open("textdatei.txt") as rd:
print(rd.closed)
Welches Ergebnis wird angezeigt?
Binär Dateien¶
Allgemeines¶
Bisher wurden nur Textdateien betrachtet, aber natürlich gibt es auch Dateien - wie z.B. Bilddateien - die nicht aus Texten bzw. Zeichenketten bestehen, sondern ganz allgemein aus beliebigen Bytes. Hierzu kann in Python an das mode-Argument in der open-Funktion ein b angehängt werden. Zudem gibt es noch ein weiteres Mode-Anhängsel + für lesenden und schreibenden Modus, bei dem insbesondere aber der Programmierer für die korrekte Positionierung des Lese-/Schreibkopfes in der Datei verantwortlich zeichnet. Hierzu gibt es die weiteren Funktionen tell und seek.
Funktion tell()¶
tell() gibt die derzeitige Position des Lese-/Schreibkopfes in der Datei als Integer-Zahl zurück und repräsentiert die Anzahl der Bytes vom Beginn der Datei an (im Textmodus ist dieser Rückgabewert unklar definiert, daher wird er im Textmodus auch nicht verwendet).
bd = open('binärdatei.xxx','wb+')
bd.write(b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
62
Funktion seek()¶
seek(offset, from_what) wird benutzt, um die Position des Lese-/Schreibkopfes in der Datei zu verändern. Die Position wird aus dem Parameter offset berechnet, ausgehend von einem entsprechenden Referenzpunkt, der durch from_what bestimmt wird. from_what=0 bedeutet von Beginn der Datei an, from_what=1 bedeutet von der derzeitigen Position ausgehend und from_what=2 bedeutet vom Ende der Datei ausgehend. Der Standardwert für from_what ist 0, also von Beginn der Datei ausgehend.
bd.seek(1)
1
Null = bd.read(1)
print(Null)
print(Null.hex())
b'1' 31
Im folgenden Beispiel springt der Lese-/Schreibkopf zum 10ten Byte in der Datei:
bd.seek(10)
10
a = bd.read(1)
print(a)
print(a.hex())
b'a' 61
Im folgenden Beispiel springt der Lese-/Schreibkopf zum 26ten Byte vor dem Ende der Datei:
bd.seek(-26, 2)
36
A = bd.read(1)
print(A)
print(A.hex())
b'A' 41
bd.close()
liste = [a,a.hex(),A,A.hex()]
liste
[b'a', '61', b'A', '41']
%%Mooc StringAssessment
ASCII Zeichen
In der obigen Datei binärdatei.xxx sind die wesentlichen Zahlen und Buchstaben der ASCII Zeichen enthalten
Geben sie die Antwort in einer Liste wie oben an
Wie lautet der Buchstabe und Hexdezimal-Code des 11ten Bytes nach dem Beginn und des 25ten Bytes vor dem Ende der Datei
%%Mooc Video
Weitere Literatur¶
%%Mooc WebReference
Reading and Writing Files
https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files
Hinweis: Detaillierter Hinweise zum Lesen und Schreiben von Dateien
%%Mooc WebReference
Builtin Functons
https://docs.python.org/3/library/functions.html
Hinweis: Detaillierte Beschreibungen der oft benutzten Builtin-Funktionen