Modulelessen (3/5)
`io` en `os`: bestanden en streams
Het lezen en schrijven van bestanden en streams in Go draait om twee complementaire pakketten: os (openen, creëren, metadata, processen) en io (de Reader/Writer interfaces die elke bytebron abstraheren).
Bestanden lezen en schrijven: de snelkoppelingen
Voor kleine of configuratiebestanden is één enkele oproep voldoende:
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 opent, leest alles in het geheugen en sluit. Perfect tot een paar MB; verder is streaming beter.
Bestanden openen voor streaming
Voor grote bestanden of incrementele toegang opent u het bestand en sluit u het met 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 wordt geopend in alleen-lezen. Om te schrijven gebruik je os.Create (wordt afgekapt als dit bestaat) of os.OpenFile(path, flag, perm) met vlaggen zoals os.O_APPEND | os.O_CREATE | os.O_WRONLY.
io.Reader en io.Writer: de universele interfaces
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }Overal waar de standaardbibliotheek een io.Reader accepteert, kunt u een bestand (*os.File), een string (strings.NewReader), een *bytes.Buffer, een HTTP-antwoord (resp.Body), een decompressor doorgeven... Hetzelfde geldt voor io.Writer.
// Copy from a Reader to a Writer (e.g. download → file).
n, err := io.Copy(dst, src)io.Copy is het werkpaard voor bytepijplijnen: het verwerkt buffering en EOF correct. io.ReadAll(r) leest alles tot EOF in een []byte.
os.Args: CLI-argumenten
os.Args is een stukje tekenreeks: index 0 is de programmanaam, vanaf 1 tot de feitelijke argumenten:
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "uso: prog <nome>")
os.Exit(1)
}
fmt.Println("ciao", os.Args[1])
}Voor meer gestructureerde parsering (vlaggen, standaardinstellingen, help) gebruikt u het pakket flag uit de stdlib of externe bibliotheken zoals cobra.
os.Stdin, os.Stdout, os.Stderr
Dit zijn drie globale *os.Files: overal waar een io.Reader of io.Writer wordt geaccepteerd, kun je ze doorgeven.
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin) // echoOefeningen
Druk het eerste opdrachtregelargument af (os.Args[1]). Als het ontbreekt, drukt u 'manca argomento' af en keert u terug.
Oplossing beschikbaar na 3 pogingen
Schrijf de string 'ciao' naar het bestand 'out.txt' met os.WriteFile (rechten 0644). Behandel de fout.
Oplossing beschikbaar na 3 pogingen
Wat is de index van de PROGRAMMANAAM in os.Args?
fmt.Println(os.Args[???])