Arbeiten mit dem Dateisystem in Go: Ein praktischer Leitfaden
Go (Golang) ist eine moderne, kompilierte Sprache, die sich hervorragend für die Entwicklung von Serveranwendungen, Dienstprogrammen und Befehlszeilentools eignet. Eine der Kernaufgaben in solchen Projekten ist die Arbeit mit dem Dateisystem. In diesem Artikel behandeln wir praktische Beispiele: vom Öffnen und Lesen von Dateien bis zum rekursiven Durchlaufen von Verzeichnissen. Alle Beispiele sind in reinem Go ohne externe Bibliotheken geschrieben.
Grundlagen: Öffnen, Lesen und Schreiben von Dateien
Das Paket os bietet Funktionen für die Low-Level-Arbeit mit Dateien. Verwenden Sie os.ReadFile (verfügbar seit Go 1.16), um den gesamten Inhalt einer Datei in den Speicher zu lesen.
package main
import ( "fmt" "os")
func main() { data, err := os.ReadFile("example.txt") if err != nil { fmt.Println("Fehler beim Lesen der Datei:", err) return } fmt.Println(string(data))}Zum Schreiben von Daten in eine Datei gibt es die Funktion os.WriteFile. Sie erstellt die Datei, falls sie nicht existiert, oder überschreibt eine vorhandene.
package main
import ( "fmt" "os")
func main() { content := []byte("Hallo, Go!Zweite Zeile") err := os.WriteFile("output.txt", content, 0644) if err != nil { fmt.Println("Fehler beim Schreiben:", err) return } fmt.Println("Datei erfolgreich geschrieben")}Das dritte Argument 0644 sind die Zugriffsrechte im Unix-Stil (Besitzer kann lesen und schreiben, andere nur lesen). Unter Windows wird dieser Parameter teilweise ignoriert.
Streaming Lesen und Schreiben: Arbeiten mit großen Dateien
Für große Dateien (mehrere Megabyte) sollten Sie diese nicht vollständig in den Speicher laden. Verwenden Sie gepuffertes Lesen mit bufio oder dem Paket io.
package main
import ( "bufio" "fmt" "os")
func main() { file, err := os.Open("large_file.log") if err != nil { fmt.Println("Fehler beim Öffnen:", err) return } defer file.Close()
scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() // Zeile verarbeiten fmt.Println(line) }
if err := scanner.Err(); err != nil { fmt.Println("Scan-Fehler:", err) }}Für das Streaming-Schreiben verwenden Sie bufio.NewWriter:
package main
import ( "bufio" "fmt" "os")
func main() { file, err := os.Create("output_stream.txt") if err != nil { fmt.Println("Fehler beim Erstellen:", err) return } defer file.Close()
writer := bufio.NewWriter(file) for i := 0; i < 10; i++ { _, err := writer.WriteString(fmt.Sprintf("Zeile %d", i+1)) if err != nil { fmt.Println("Fehler beim Schreiben:", err) return } } writer.Flush() // Wichtig: Puffer leeren fmt.Println("Schreiben abgeschlossen")}Die Methode Flush() ist obligatorisch – ohne sie könnten Daten im Puffer verbleiben und nicht in die Datei gelangen.
Arbeiten mit Verzeichnissen: Erstellen, Löschen und Durchlaufen
Ein neues Verzeichnis kann mit os.Mkdir (ein Ordner) oder os.MkdirAll (rekursiv, wie mkdir -p) erstellt werden.
package main
import ( "fmt" "os")
func main() { // Einen Ordner erstellen err := os.Mkdir("new_folder", 0755) if err != nil { fmt.Println("Fehler beim Erstellen des Ordners:", err) }
// Verschachtelte Struktur erstellen err = os.MkdirAll("a/b/c/d", 0755) if err != nil { fmt.Println("Fehler beim Erstellen der verschachtelten Ordner:", err) } else { fmt.Println("Ordner erstellt") }}Das Löschen eines Verzeichnisses erfolgt mit os.Remove (nur l