Direkt zum Hauptinhalt springen
eLearner.app
Modul 8 · Lektion 3 von 538/50 im Kurs~14 min
Lektionen des Moduls (3/5)

`io` und `os`: Dateien und Streams

Das Lesen und Schreiben von Dateien und Streams in Go dreht sich um zwei komplementäre Pakete: os (Öffnen, Erstellen, Metadaten, Prozesse) und io (die Reader/Writer-Schnittstellen, die jede Bytequelle abstrahieren).

Dateien lesen und schreiben: die Verknüpfungen

Für kleine oder Konfigurationsdateien reicht ein einziger Aufruf:

Go
data, err := os.ReadFile("input.txt")        // returns []byte
if err != nil {
    return err
}
fmt.Println(string(data))

err = os.WriteFile("out.txt", []byte("ciao"), 0644)

os.ReadFile öffnet sich, liest alles in den Speicher und schließt sich. Perfekt bis zu ein paar MB; darüber hinaus ist Streaming besser.

Dateien zum Streamen öffnen

Für große Dateien oder inkrementellen Zugriff öffnen Sie die Datei und schließen Sie sie mit defer:

Go
f, err := os.Open("big.txt")        // read-only
if err != nil {
    return err
}
defer f.Close()

buf := make([]byte, 4096)
for {
    n, err := f.Read(buf)
    if n > 0 {
        process(buf[:n])
    }
    if err == io.EOF {
        break
    }
    if err != nil {
        return err
    }
}

os.Open wird schreibgeschützt geöffnet. Zum Schreiben verwenden Sie os.Create (kürzt, falls vorhanden) oder os.OpenFile(path, flag, perm) mit Flags wie os.O_APPEND | os.O_CREATE | os.O_WRONLY.

io.Reader und io.Writer: die universellen Schnittstellen

Go
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }

Überall dort, wo die Standardbibliothek einen io.Reader akzeptiert, können Sie eine Datei (*os.File), einen String (strings.NewReader), einen *bytes.Buffer, eine HTTP-Antwort (resp.Body), einen Dekomprimierer usw. übergeben. Das Gleiche gilt für io.Writer.

Go
// Copy from a Reader to a Writer (e.g. download → file).
n, err := io.Copy(dst, src)

io.Copy ist das Arbeitstier für Byte-Pipelines: Es verarbeitet Pufferung und EOF korrekt. io.ReadAll(r) liest alles bis EOF in einen []byte.

os.Args: CLI-Argumente

os.Args ist ein Segment von Zeichenfolgen: Index 0 ist der Programmname, ab 1 die tatsächlichen Argumente:

Go
func main() {
    if len(os.Args) < 2 {
        fmt.Fprintln(os.Stderr, "uso: prog <nome>")
        os.Exit(1)
    }
    fmt.Println("ciao", os.Args[1])
}

Für eine strukturiertere Analyse (Flags, Standardeinstellungen, Hilfe) verwenden Sie das flag-Paket aus der stdlib oder externe Bibliotheken wie cobra.

os.Stdin, os.Stdout, os.Stderr

Dies sind drei globale *os.Files: Überall dort, wo ein io.Reader oder io.Writer akzeptiert wird, können Sie diese übergeben.

Go
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin)  // echo

Übungen

Übung#go.m8.l3.e1
Versuche: 0Wird geladen…

Geben Sie das erste Befehlszeilenargument aus (os.Args[1]). Wenn es fehlt, geben Sie „manca argomento“ ein und senden Sie es zurück.

Editor wird geladen…

Lösung nach 3 Versuchen verfügbar

Übung#go.m8.l3.e2
Versuche: 0Wird geladen…

Schreiben Sie die Zeichenfolge „ciao“ mit os.WriteFile (Berechtigungen 0644) in die Datei „out.txt“. Behandeln Sie den Fehler.

Editor wird geladen…

Lösung nach 3 Versuchen verfügbar

Quiz#go.m8.l3.e3
Bereit

Was ist der Index des PROGRAMMNAMEN in os.Args?

Go
fmt.Println(os.Args[???])
Antwortoptionen