Lettura File

Per la gestione dei file vi sono vari package:

  • io - funzioni primarie a basso livello
  • ioutil - funzioni di utility a basso livello
  • bufio - funzioni di I/O bufferizzato
  • os - funzioni ad alto livello

Ecco un esempio dell'uso di questi package per la lettura da file.

(560reading-files.go):

package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

// Funzione che controlla se c'è stato un errore
func check(e error) {
	if e != nil {
		panic(e)
	}
}

func main() {

	// Legge l'intero file in memoria in un colpo solo
	dat, err := ioutil.ReadFile("/tmp/dat")
	// Controlla l'errore
	check(err)
	// Lo stampa in un colpo solo
	// assicurandosi che sia una stringa
	fmt.Print(string(dat))

	// Solo apertura del file
	// non specifica se in lettura o scrittura
	f, err := os.Open("/tmp/dat")
	check(err)
	// f è una struct che contiene l'indirizzo del file
	fmt.Printf("%+v\n", *f)

	// Un file può essere aperto più volte
	g, err := os.Open("/tmp/dat")
	defer g.Close()

	// Lettura di 5 byte dal file
	b1 := make([]byte, 5)
	// Ritorna quanti byte sono stati letti e un errore
	n1, err := f.Read(b1)
	check(err)
	fmt.Printf("%d bytes: %s\n", n1, string(b1))

	// Salto al sesto byte a partire dalla posizione 0 (inizio)
	o2, err := f.Seek(6, 0)
	check(err)
	// Lettura di 2 byte
	b2 := make([]byte, 2)
	n2, err := f.Read(b2)
	check(err)
	fmt.Printf("%d bytes @ %d: %s\n", n2, o2, string(b2))

	// Ritorna al sesto byte dall'inizio
	o3, err := f.Seek(6, 0)
	check(err)
	// Legge 'almeno' 2 byte
	// Notare il package 'io'
	b3 := make([]byte, 2)
	n3, err := io.ReadAtLeast(f, b3, 2)
	check(err)
	fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3))

	// Opera dall'inizio del file
	// se il secondo argomento è zero
	// Qui ritorna all'inizio del file
	_, err = f.Seek(0, 0)
	check(err)

	// E' possibile leggere dalla fine del file
	// se il secondo argomento è 2
	// Naturalmente il primo argomento è negativo
	_, err = f.Seek(-50, 2)
	check(err)
	bz := make([]byte, 50)
	nz, err := f.Read(bz)
	check(err)
	fmt.Printf("%d bytes: %s\n", nz, string(bz))
	// Per un seek dalla posizione corrente il
	// secondo argomento è 1

	// Uso di un reader bufferizzato
	// Ricordarsi di risettare il file all'inizio
	// Il tentativo di leggere oltre EOF da panic
	_, err = f.Seek(0, 0)
	check(err)
	// Costruisce il buffer
	r4 := bufio.NewReader(f)
	// Acquisisce dal puntatore al 50 carattere
	b4, err := r4.Peek(50)
	check(err)
	// Non sposta il puntatore, questo è dall'inizio
	fmt.Printf("5 bytes: %s\n", string(b4))

	// Al termine chiudere il file
	// Di solito compiuto con un defer
	f.Close()
}