Salt la conținutul principal
Modulul 8 · Lecția 3 din 538/50 în curs~14 min
Lecții din modul (3/5)

`io` și `os`: fișiere și fluxuri

Citirea și scrierea fișierelor și fluxurilor în Go se învârte în jurul a două pachete complementare: os (deschidere, creare, metadate, procese) și io (Reader/Writer care abstrac orice sursă de interfețe).

Citirea și scrierea fișierelor: comenzile rapide

Pentru fișiere mici sau de configurare, este suficient un singur apel:

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 se deschide, citește totul în memorie și se închide. Perfect până la câțiva MB; dincolo de asta, streaming-ul este mai bine.

Deschiderea fișierelor pentru streaming

Pentru fișiere mari sau acces incremental, deschideți fișierul și închideți-l cu 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 se deschide doar în citire. Pentru a scrie, utilizați os.Create (trunchiază dacă există) sau os.OpenFile(path, flag, perm) cu indicatoare precum os.O_APPEND | os.O_CREATE | os.O_WRONLY.

io.Reader și io.Writer: interfețele universale

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

Oriunde biblioteca standard acceptă un io.Reader, puteți transmite un fișier (*os.File), un șir (strings.NewReader), un *bytes.Buffer, un răspuns HTTP (PROTECTED_INLINE), un șir de caractere (strings.NewReader), un răspuns HTTP (PROTECTED_INLINE), un io.Writer.

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

io.Copy este calul de lucru pentru conductele de octeți: gestionează corect tamponarea și EOF. io.ReadAll(r) citește totul până la EOF într-un []byte.

os.Args: argumente CLI

os.Args este o porțiune de șiruri de caractere: indexul 0 este numele programului, de la 1 pe argumentele reale:

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

Pentru o analiză mai structurată (steaguri, valori implicite, ajutor) utilizați pachetul flag din stdlib sau biblioteci externe precum cobra.

os.Stdin, os.Stdout, os.Stderr

Acestea sunt trei *os.File-uri globale: oriunde este acceptată un io.Reader sau io.Writer, le puteți trece.

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

Exerciții

Exercițiu#go.m8.l3.e1
Încercări: 0Se încarcă…

Tipăriți primul argument din linia de comandă (os.Args[1]). Dacă lipsește, tipăriți „manca argomento” și returnați.

Se încarcă editorul...

Soluție disponibilă după 3 încercări

Exercițiu#go.m8.l3.e2
Încercări: 0Se încarcă…

Scrieți șirul „ciao” în fișierul „out.txt” cu os.WriteFile (permisiuni 0644). Gestionați eroarea.

Se încarcă editorul...

Soluție disponibilă după 3 încercări

Quiz#go.m8.l3.e3
Gata

Care este indexul NUMELE PROGRAMULUI în os.Args?

Go
fmt.Println(os.Args[???])
Opțiuni de răspuns