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:
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:
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
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.
// 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:
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.
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin) // echoÜbungen
Geben Sie das erste Befehlszeilenargument aus (os.Args[1]). Wenn es fehlt, geben Sie „manca argomento“ ein und senden Sie es zurück.
Lösung nach 3 Versuchen verfügbar
Schreiben Sie die Zeichenfolge „ciao“ mit os.WriteFile (Berechtigungen 0644) in die Datei „out.txt“. Behandeln Sie den Fehler.
Lösung nach 3 Versuchen verfügbar
Was ist der Index des PROGRAMMNAMEN in os.Args?
fmt.Println(os.Args[???])