Read Files (Dateien lesen)
Kurz: Daten aus einer bestehenden Datei ins Programm einlesen — entweder auf einmal komplett oder schrittweise (zeilen- oder blockweise), um auch sehr große Dateien verarbeiten zu können, ohne sie komplett in den Arbeitsspeicher zu laden.
Genauer: Für Textdateien bieten viele Sprachen gepufferte Lese-Hilfsklassen an (siehe BufferedReader), die effizienter sind als einzelne, ungepufferte Lesezugriffe. Ein häufiger Fehler ist, das Ende der Datei nicht korrekt zu erkennen und dadurch entweder Daten zu verlieren oder eine Exception auszulösen, wenn versucht wird, über das Dateiende hinaus zu lesen.
Im Detail
Die Wahl zwischen “auf einmal komplett laden” und “schrittweise lesen” ist eine der wichtigsten Entscheidungen bei Dateiverarbeitung:
# Komplett laden - einfach, aber bei großen Dateien speicherintensiv
with open("datei.txt") as f:
gesamter_inhalt = f.read()
# Zeilenweise - konstanter Speicherbedarf, egal wie groß die Datei ist
with open("datei.txt") as f:
for zeile in f:
verarbeite(zeile)Bei einer 5-KB-Konfigurationsdatei spielt der Unterschied keine Rolle. Bei einer 50-GB-Logdatei entscheidet er darüber, ob das Programm überhaupt funktioniert — komplettes Laden würde versuchen, alle 50 GB gleichzeitig in den Arbeitsspeicher zu laden, was meist scheitert oder das System massiv verlangsamt. Zeilenweises (oder allgemeiner: blockweises) Lesen hält immer nur einen kleinen Ausschnitt im Speicher, unabhängig von der Gesamtgröße der Datei.
Intern ist das häufig mit einem Puffer verbunden (siehe BufferedReader): Statt bei jedem einzelnen Lesezugriff physisch auf den Datenträger zuzugreifen (langsam), liest die Laufzeitumgebung größere Blöcke auf einmal in einen Zwischenspeicher und bedient einzelne Leseanfragen des Programms daraus — deutlich schneller, besonders bei vielen kleinen Lesezugriffen hintereinander.
Ein häufiger Anfängerfehler ist die falsche Behandlung des Dateiendes (EOF, “End of File”): Wird versucht, über das Ende hinaus zu lesen, geben manche APIs einen speziellen Wert zurück (z. B. -1 oder None), andere lösen eine Exception aus — welches Verhalten die verwendete Sprache/Bibliothek zeigt, muss man kennen, sonst entstehen entweder Endlosschleifen (die Abbruchbedingung wird nie erreicht) oder unbehandelte Abstürze.
Siehe auch: Files, BufferedReader