В области компьютерных и информационных технологий I/O
этот термин означает ввод/вывод (англ. Input/Output), обычно относится к вводу и выводу данных между памятью (внутренней и внешней) или другими периферийными устройствами, представляет собой систему обработки информации и внешняя связь. Входы — это сигналы или данные, полученные системой, а выходы — это сигналы или данные, отправленные из нее.
I/O
В языке Go существует множество встроенных библиотек , задействованных в операциях , таких как: io
библиотека, os
библиотека, ioutil
библиотека, bufio
библиотека, bytes
библиотека , библиотека и strings
т. д. Хорошо иметь так много встроенных библиотек, но I/O
какую библиотеку мы должны выбрать, когда речь идет о задействованных сценариях?
io.Чтение/Писатель
Язык Go использует io.Reader
и io.Writer
два интерфейса для абстракции I/O
, их определения следующие.
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
io.Reader
Интерфейс представляет объект, из которого можно прочитать поток байтов, и объект, в который io.Writer
можно записать поток байтов.
Несколько часто используемых реализаций io.Reader/Writer
-
net.Conn: представляет сетевое подключение. -
os.Stdin, os.Stdout, os.Stderr: стандартный ввод, вывод и ошибка. -
os.File: сеть, стандартный ввод и вывод, потоковое чтение файлов. -
strings.Reader: строки абстрагируются в реализацию io.Reader. -
bytes.Reader: []byte абстрагируется от реализации io.Reader. -
bytes.Buffer: []byte абстрагируется от реализации io.Reader и io.Writer. -
bufio.Reader/Writer: Чтение и запись буферизованного потока (например, построчно).
В дополнение к этим реализациям ioutil
библиотека инструментов содержит множество функций инструментов ввода-вывода, а встроенная библиотека, связанная с кодированием encoding/base64
и т. д., encoding/binary
также реализует соответствующие функции кодирования через io.Reader и io.Writer.
Связь между этими общими реализациями и библиотеками инструментов и io.Reader и io.Writer может быть представлена на следующей диаграмме.

Сценарии использования для каждой библиотеки ввода/вывода
io библиотека
io
Библиотеки принадлежат базовой библиотеке определения интерфейса. Его основная функция состоит в том, чтобы определять I/O
основные интерфейсы и основные константы, а также объяснять функции этих интерфейсов. При написании кода для выполнения I/O
операций эта библиотека обычно используется только для вызова ее констант и определений интерфейса, например, для определения того, был io.EOF
ли он прочитан, и для использования io.Reader
ее в качестве объявления типа переменных.
// 字节流读取完后,会返回io.EOF这个error
for {
n, err := r.Read(buf)
fmt.Println(n, err, buf[:n])
if err == io.EOF {
break
}
}
библиотека ОС
os
Библиотека в основном занимается работой операционной системы и действует как мост для взаимодействия между программой Go и операционной системой. Операции по созданию файлов, открытию или закрытию файлов, сокетов и т. д. связаны с операционной системой, поэтому все они os
выполняются через библиотеки. Эта библиотека часто используется вместе с ioutil
, bufio
и т.д.
библиотека ioutil
ioutil
Библиотека представляет собой набор инструментов, который предоставляет множество полезных функций инструмента ввода-вывода, таких как ReadAll, ReadFile, WriteFile, ReadDir. Единственное, что следует отметить, это то, что все они одноразового чтения и одноразовой записи, поэтому при его использовании необходимо обращать внимание на размер файла, особенно при одновременном чтении данных из файла в память.
Прочитать все в файле
func readByFile() {
data, err := ioutil.ReadFile( "./file/test.txt")
if err != nil {
log.Fatal("err:", err)
return
}
fmt.Println("data", string(data))
}
Записать данные в файл сразу
func writeFile() {
err := ioutil.WriteFile("./file/write_test.txt", []byte("hello world!"), 0644)
if err != nil {
panic(err)
return
}
}
библиотека буфио
bufio, который можно понимать как io
дополнительный слой кэша на базе библиотеки, предоставляет множество функций для чтения и записи построчно, от побайтового чтения и записи в библиотеке io до построчного чтения и записи .Для написания кода все же намного удобнее.
func readBigFile(filePath string) error {
f, err := os.Open(filePath)
defer f.Close()
if err != nil {
log.Fatal(err)
return err
}
buf := bufio.NewReader(f)
count := 0
// 循环中打印前100行内容
for {
count += 1
line, err := buf.ReadString('\n')
line = strings.TrimSpace(line)
if err != nil {
return err
}
fmt.Println("line", line)
if count > 100 {
break
}
}
return nil
}
-
Методы ReadLine и ReadString: buf.ReadLine(), buf.ReadString("\n") читаются построчно, но ReadLine считывает []byte, который считывает строку напрямую, и, наконец, они вызывают нижний слой. Оба метода являются ReadSlice . -
Библиотека bufio VS ioutil: библиотеки bufio и ioutil обеспечивают возможность чтения и записи файлов. Единственная разница между ними в том, что у bufio есть дополнительный уровень кэширования. Это преимущество в основном проявляется при чтении больших файлов.
библиотека байтов и строк
Bytes.Reader и string.Reader в библиотеках bytes и strings реализуют io.Reader
интерфейс, а также предоставляют метод NewReader для непосредственного создания соответствующей реализации Reader из переменной типа []byte
или типа.string
r := strings.NewReader("abcde")
// 或者是 bytes.NewReader([]byte("abcde"))
buf := make([]byte, 4)
for {
n, err := r.Read(buf)
fmt.Println(n, err, buf[:n])
if err == io.EOF {
break
}
}
Еще одно отличие состоит в том, что библиотека bytes имеет функциональность Buffer, а библиотека strings — нет.
var buf bytes.Buffer
fmt.Fprintf(&buf, "Size: %d MB.", 85)
s := buf.String()) // s == "Size: 85 MB."
Подвести итог
Что касается интерфейса io.Reader
, io.Writer
его можно просто понимать как источник чтения и источник записи. То есть, пока Reader
метод Read
реализован, эта штука может использоваться как источник чтения, который может содержать данные и быть прочитанным нами. Writer
тоже так.
Выше приведено краткое изложение сценариев использования и проблем, которые необходимо решить каждой библиотеке для встроенных библиотек языка Go, которые я часто использую при выполнении I/O
операций на языке Go.Правильно выбрать соответствующую библиотеку, когда это необходимо для завершения I/O
операция. Если описание в статье неверное, пожалуйста, оставьте сообщение для его исправления, а также вы можете обсудить и внести предложения по содержанию статьи в сообщении.
Рекомендуемое чтение: