Хех, мне нравится трюк, показывающий, что (* os.File) является io.Reader без возможности открывать файлы с игровой площадки.
twotwotwo 05
@twotwotwo, что именно делает этот хак? Я предполагаю, что синтаксически он говорит о пустом файле, поэтому никогда не пытается что-либо открыть.
mschuett
7
@mschuett Более или менее: это nilуказатель правильного типа, указывающий на os.File. (В этом случае вы действительно ничего не можете сделать через него.) И var _ io.Reader = (*os.File)(nil)назначение заставляет компилятор проверять, что *os.Fileэто io.Reader(иначе присвоение было бы недействительным). Если вы перейдете на площадку и переключитесь *os.Fileна, *os.Processвы увидите ошибку, которую он генерирует для вещей, которые не соответствуют интерфейсу.
twotwotwo
2
@fabrizioM, где именно в документации сказано, что * os.File реализует Reader. Иначе, без этого ответа, как бы вы могли понять себя, просто прочитав официальный документ? Хорошо, я вижу func (f *File) Read(b []byte) (n int, err error), как в Reader.
func Open (строка имени) (файл * файл, ошибка ошибки)
Открыть открывает указанный файл для чтения. В случае успеха методы возвращенного файла можно использовать для чтения; связанный дескриптор файла имеет режим O_RDONLY. Если есть ошибка, она будет типа * PathError.
Возвращаемое значение типа *os.Fileреализует io.Readerинтерфейс.
Тип * os.File реализует интерфейс io.Reader, поэтому вы можете вернуть файл как Reader. Но я рекомендую вам использовать пакет bufio , если вы собираетесь читать большие файлы, примерно так:
Не могли бы вы пояснить, почему вы рекомендуете bufioдля больших файлов?
Чиро Коста
1
@CiroCosta, если у вас есть огромный файл в Гб, вы не хотите полностью читать его в памяти, поэтому для таких случаев мы должны использовать буфер
Яндри Посо
среда выполнения go использует буферы в разумных ситуациях, например, io.Copy будет повторно использовать нижележащие буферы, если их интерфейс доступен - в противном случае он создаст внутренний буфер
colm.anseo
1
Спасибо за path/file.ext. Никакой другой ответ не объяснял, что os.Fileбыло.
Azurespot
5
Вот пример, в котором мы открываем текстовый файл и создаем io.Reader из возвращенного экземпляра * 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
}
Ответы:
os.Open
возвращает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") }
источник
nil
указатель правильного типа, указывающий наos.File
. (В этом случае вы действительно ничего не можете сделать через него.) Иvar _ io.Reader = (*os.File)(nil)
назначение заставляет компилятор проверять, что*os.File
этоio.Reader
(иначе присвоение было бы недействительным). Если вы перейдете на площадку и переключитесь*os.File
на,*os.Process
вы увидите ошибку, которую он генерирует для вещей, которые не соответствуют интерфейсу.func (f *File) Read(b []byte) (n int, err error)
, как вReader
.Используйте os.Open () :
Возвращаемое значение типа
*os.File
реализуетio.Reader
интерфейс.источник
Тип * os.File реализует интерфейс io.Reader, поэтому вы можете вернуть файл как Reader. Но я рекомендую вам использовать пакет bufio , если вы собираетесь читать большие файлы, примерно так:
file, err := os.Open("path/file.ext") // if err != nil { ... } return bufio.NewReader(file)
источник
bufio
для больших файлов?path/file.ext
. Никакой другой ответ не объяснял, чтоos.File
было.Вот пример, в котором мы открываем текстовый файл и создаем io.Reader из возвращенного экземпляра * 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 }
источник