Crea un io.Reader da un file locale


89

Vorrei aprire un file locale e restituire un file io.Reader. Il motivo è che devo fornire io.Readera una libreria che sto utilizzando, come:

func read(r io.Reader) (results []string) {

}

1
Probabilmente vale la pena spendere un po 'di tempo a navigare in golang.org/pkg e, per il tipo di cosa che sembra che tu stia facendo, os, io, io / ioutil e bufio.
twotwotwo

Risposte:


117

os.Open restituisce un io.Reader

http://play.golang.org/p/BskGT09kxL

package main

import (
    "fmt"
    "io"
    "os"
)

var _ io.Reader = (*os.File)(nil)

func main() {
    fmt.Println("Hello, playground")
}

30
Heh, adoro il trucco per mostrare che (* os.File) è un io.Reader senza essere in grado di aprire i file dal Playground.
twotwotwo

@twotwotwo cosa fa esattamente questo hack. Presumo sintatticamente che stia dicendo un file di niente, quindi non prova mai ad aprire nulla.
mschuett

7
@mschuett Più o meno: è un nilpuntatore del tipo giusto per puntare a un file os.File. (In questo caso, non puoi davvero fare nulla attraverso di esso.) E l' var _ io.Reader = (*os.File)(nil)assegnazione fa in modo che il compilatore controlli che *os.Filesia un io.Reader(altrimenti l'assegnazione non sarebbe valida). Se vai al Playground e cambi *os.Filein *os.Processvedrai l'errore che genera per cose che non soddisfano l'interfaccia.
due il

2
@fabrizioM dove esattamente nella documentazione si dice che * os.File implementa un Reader. Altrimenti, senza questa risposta come potresti capire da solo leggendo un documento ufficiale? Ok, lo vedo func (f *File) Read(b []byte) (n int, err error), lo stesso di Reader.
Aliaksandr Kazlou

43

Usa os.Open () :

func Open (stringa del nome) (file * File, errore err)

Apri apre il file denominato per la lettura. In caso di successo, i metodi sul file restituito possono essere utilizzati per la lettura; il descrittore di file associato ha la modalità O_RDONLY. Se c'è un errore, sarà di tipo * PathError.

Il valore restituito di tipo *os.Fileimplementa l' io.Readerinterfaccia.


27

Il tipo * os.File implementa l'interfaccia io.Reader, quindi puoi restituire il file come Reader. Ma ti consiglio di usare il pacchetto bufio se hai intenzione di leggere file di grandi dimensioni, qualcosa del genere:

file, err := os.Open("path/file.ext")
// if err != nil { ... }

return bufio.NewReader(file)

4
Potresti spiegare perché consigli bufioper file di grandi dimensioni?
Ciro Costa

1
@CiroCosta se hai un file enorme di Gbs non vuoi leggerlo completamente in memoria, quindi per quei casi dovremmo usare un buffer
Yandry Pozo

Il runtime di go utilizza i buffer in situazioni sensibili, ad esempio io.Copy riutilizzerà i buffer sottostanti se la loro interfaccia è disponibile - altrimenti creerà un buffer interno
colm.anseo

1
Grazie per path/file.ext. Nessun'altra risposta specificava cosa os.Filefosse.
Azurespot

5

Ecco un esempio in cui apriamo un file di testo e creiamo un io.Reader dall'istanza f di * os.File restituita

package main

import (
    "io"
    "os"
)

func main() {
    f, err := os.Open("somefile.txt")
    if err != nil {
        panic(err)
    }
    defer f.Close()

    var r io.Reader
    r = f
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.