Arbeiten mit dem Dateisystem in Go: für Anfänger
Go (Golang) ist eine moderne, kompilierte Sprache, die für ihre Einfachheit, Leistung und integrierten Werkzeuge bekannt ist. Eine der Schlüsselaufgaben jedes Backend-Entwicklers ist die Interaktion mit dem Dateisystem: Lesen von Konfigurationen, Schreiben von Logs, Erstellen temporärer Dateien und Verzeichnisse. In diesem Artikel werden wir die grundlegenden Operationen mit Dateien und Ordnern in Go behandeln, angefangen bei den Grundlagen. Das Material richtet sich an Anfänger, daher wird jeder Schritt von verständlichen Codebeispielen begleitet.
Wichtige Pakete für die Dateiarbeit
In der Standardbibliothek von Go gibt es zwei Hauptpakete für die Arbeit mit dem Dateisystem:
os— Low-Level-Arbeit mit Dateien, Ordnern, Zugriffsrechten und Prozessen.io/ioutil(veraltet in Go 1.16, aber immer noch anzutreffen) — praktische Funktionen zum vollständigen Lesen/Schreiben von Dateien.io— Schnittstellen für Stream-Eingabe/-Ausgabe.bufio— gepuffertes Lesen/Schreiben (nützlich für große Dateien).
Ab Go 1.16 wird empfohlen, Funktionen aus dem Paket os (os.ReadFile, os.WriteFile) anstelle von ioutil zu verwenden. Wir werden uns auf den modernen Ansatz stützen.
Dateien lesen
Der einfachste Weg, eine kleine Datei vollständig zu lesen, ist die Verwendung von os.ReadFile. Es gibt ein Byte-Slice und einen Fehler zurück.
package main
import ( "fmt" "os")
func main() { // Datei vollständig lesen data, err := os.ReadFile("example.txt") if err != nil { fmt.Println("Fehler beim Lesen der Datei:", err) return } fmt.Println("Dateiinhalt:") fmt.Println(string(data))}Wenn die Datei groß ist (z. B. eine Logdatei mit mehreren hundert Megabyte), ist es besser, sie zeilenweise oder blockweise mit bufio.Scanner zu lesen:
package main
import ( "bufio" "fmt" "os")
func main() { file, err := os.Open("bigfile.log") if err != nil { fmt.Println("Fehler beim Öffnen der Datei:", err) return } defer file.Close() // Datei unbedingt schließen
scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() fmt.Println(line) // Zeile verarbeiten }
if err := scanner.Err(); err != nil { fmt.Println("Fehler beim Scannen:", err) }}Beachten Sie defer file.Close() — dies stellt sicher, dass die Datei nach Beendigung der Funktion geschlossen wird, selbst wenn ein Fehler auftritt.
In Dateien schreiben
Verwenden Sie zum Schreiben von Daten in eine Datei os.WriteFile (erstellt/überschreibt die Datei) oder os.Create + Write (für flexibleres Schreiben).
package main
import ( "fmt" "os")
func main() { // Einfaches Schreiben eines Strings in eine Datei text := "Hallo, Welt!Zweite Zeile." err := os.WriteFile("output.txt", []byte(text), 0644) if err != nil { fmt.Println("Fehler beim Schreiben:", err) return } fmt.Println("Datei erfolgreich geschrieben")}Der Parameter 0644 sind die Zugriffsrechte im Unix-Stil (Eigentümer kann lesen/schreiben, andere nur lesen).
Wenn Sie Daten an das Ende einer Datei anhängen möchten (append), verwenden Sie os.OpenFile mit dem Flag os.O_APPEND:
package main
import ( "fmt" "os")
func main() { file, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Println("Fehler beim Öffnen der Datei:", err) return } defer file.Close()
_, err = file.WriteString("Neuer Logeintrag") if err != nil { fmt.Println("Fehler beim Schreiben:", err) }}