Heh, uwielbiam tę sztuczkę pokazującą, że (* os.File) jest czytnikiem io.Reader bez możliwości otwierania plików z Playground.
twotwotwo
@twotwotwo, co dokładnie robi ten hack. Zakładam, że składniowo mówi o pliku niczego, więc nigdy nie próbuje niczego otwierać.
mschuett,
7
@mschuett Mniej więcej: jest to nilwskaźnik odpowiedniego typu, który wskazuje na plik os.File. (W tym przypadku tak naprawdę nie możesz nic przez to zrobić). A var _ io.Reader = (*os.File)(nil)przypisanie powoduje, że kompilator sprawdza, czy to *os.Filejest io.Reader(inaczej przypisanie nie byłoby prawidłowe). Jeśli przejdziesz do Playground i zmienisz *os.Filena *os.Process, zobaczysz błąd, który generuje dla rzeczy, które nie odpowiadają interfejsowi.
twotwotwo
2
@fabrizioM gdzie dokładnie w dokumentacji jest napisane, że * os.File implementuje czytnik. W przeciwnym razie, bez tej odpowiedzi, jak mógłbyś zrozumieć siebie, czytając po prostu oficjalny dokument? Ok, widzę to func (f *File) Read(b []byte) (n int, err error)samo co w Reader.
Otwórz otwiera nazwany plik do odczytu. Jeśli się powiedzie, do odczytu można użyć metod zwróconego pliku; powiązany deskryptor pliku ma tryb O_RDONLY. Jeśli wystąpi błąd, będzie to typ * PathError.
Zwrócona wartość typu *os.Fileimplementuje io.Readerinterfejs.
Typ * os.File implementuje interfejs io.Reader, więc możesz zwrócić plik jako Reader. Ale polecam skorzystać z pakietu bufio , jeśli masz zamiar czytać duże pliki, coś takiego:
Czy mógłbyś wyjaśnić, dlaczego polecasz bufioduże pliki?
Ciro Costa
1
@CiroCosta, jeśli masz ogromny plik Gbs, nie chcesz go odczytać w całości w pamięci, więc w takich przypadkach powinniśmy użyć bufora
Yandry Pozo
Środowisko wykonawcze go używa buforów w rozsądnych sytuacjach, np. io.Copy użyje ponownie bazowych buforów, jeśli ich interfejs jest dostępny - w przeciwnym razie utworzy bufor wewnętrzny
colm.anseo
1
Dzięki za path/file.ext. Żadna inna odpowiedź nie wyjaśniała, co os.Filebyło.
Azurespot
5
Oto przykład, w którym otwieramy plik tekstowy i tworzymy io.Reader z zwróconej instancji * os.File f
package main
import (
"io""os"
)
funcmain() {
f, err := os.Open("somefile.txt")
if err != nil {
panic(err)
}
defer f.Close()
var r io.Reader
r = f
}
Odpowiedzi:
os.Open
zwraca plikio.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") }
źródło
nil
wskaźnik odpowiedniego typu, który wskazuje na plikos.File
. (W tym przypadku tak naprawdę nie możesz nic przez to zrobić). Avar _ io.Reader = (*os.File)(nil)
przypisanie powoduje, że kompilator sprawdza, czy to*os.File
jestio.Reader
(inaczej przypisanie nie byłoby prawidłowe). Jeśli przejdziesz do Playground i zmienisz*os.File
na*os.Process
, zobaczysz błąd, który generuje dla rzeczy, które nie odpowiadają interfejsowi.func (f *File) Read(b []byte) (n int, err error)
samo co wReader
.Użyj os.Open () :
Zwrócona wartość typu
*os.File
implementujeio.Reader
interfejs.źródło
Typ * os.File implementuje interfejs io.Reader, więc możesz zwrócić plik jako Reader. Ale polecam skorzystać z pakietu bufio , jeśli masz zamiar czytać duże pliki, coś takiego:
file, err := os.Open("path/file.ext") // if err != nil { ... } return bufio.NewReader(file)
źródło
bufio
duże pliki?path/file.ext
. Żadna inna odpowiedź nie wyjaśniała, coos.File
było.Oto przykład, w którym otwieramy plik tekstowy i tworzymy io.Reader z zwróconej instancji * os.File f
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 }
źródło