Тип bufio.Reader
Тип bufio.Reader представляет собой буферизированный ридер,
который оборачивает стандартный ридер (например, os.Stdin
или strings.Reader) и предоставляет дополнительные методы
для удобного чтения данных. Буферизация позволяет уменьшить
количество системных вызовов при чтении данных, что повышает
производительность. В первый параметр функции bufio.NewReader
мы передаем источник данных (ридер), а результатом работы является
указатель на новый экземпляр bufio.Reader.
Создание ридера
Для создания буферизированного ридера используется функция
bufio.NewReader, которая принимает интерфейс io.Reader.
Рассмотрим базовый пример создания ридера из строки:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
str := "abcde"
reader := bufio.NewReader(strings.NewReader(str))
fmt.Println(reader)
}
Результат выполнения кода:
&{0xc0000120c0 0 0 0 0}
Метод ReadString
Метод ReadString читает данные из буфера до тех пор,
пока не встретит указанный разделитель (обычно это символ
новой строки). Он возвращает прочитанную строку вместе
с разделителем. В первый параметр метода мы передаем
разделитель в виде байта, а результатом является строка
и ошибка:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
str := "Hello\nWorld\nGo"
reader := bufio.NewReader(strings.NewReader(str))
line, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(line)
}
Результат выполнения кода:
"Hello\n"
Метод ReadBytes
Метод ReadBytes работает аналогично ReadString,
но возвращает срез байтов вместо строки. Это полезно,
когда мы работаем с бинарными данными или когда строка
может содержать невалидные UTF-8 символы:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
data := "12345\n67890"
reader := bufio.NewReader(strings.NewReader(data))
bytes, err := reader.ReadBytes('\n')
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(bytes)
}
Результат выполнения кода:
[49 50 51 52 53 10]
Метод ReadLine
Метод ReadLine читает строку текста и возвращает
ее в виде среза байтов без завершающего символа новой
строки. В отличие от ReadString, этот метод удаляет
разделитель. Результатом работы метода являются срез
байтов, булев флаг (указывающий, была ли строка слишком
длинной) и ошибка:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
text := "First line\nSecond line"
reader := bufio.NewReader(strings.NewReader(text))
line, isPrefix, err := reader.ReadLine()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(line))
fmt.Println("isPrefix:", isPrefix)
}
Результат выполнения кода:
"First line"
"isPrefix: false"
Метод Peek
Метод Peek позволяет заглянуть вперед на указанное
количество байтов, не извлекая их из буфера. Это полезно,
когда нужно проверить следующие данные перед тем, как
принять решение о чтении. В первый параметр передается
количество байтов для просмотра, а результатом является
срез байтов и ошибка:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
data := "12345"
reader := bufio.NewReader(strings.NewReader(data))
peeked, err := reader.Peek(3)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(peeked)
fmt.Println(string(peeked))
// Буфер не изменился, можем прочитать полностью
all, _ := reader.ReadString('\n')
fmt.Println(all)
}
Результат выполнения кода:
[49 50 51]
"123"
"12345"
Метод Discard
Метод Discard пропускает указанное количество байтов
из буфера, не возвращая их. Это полезно, когда нужно
пропустить неинтересующие нас данные. В первый параметр
передается количество байтов для пропуска, а результатом
является количество реально пропущенных байтов и ошибка:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
data := "abcde"
reader := bufio.NewReader(strings.NewReader(data))
discarded, err := reader.Discard(2)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Discarded:", discarded)
remaining, _ := reader.ReadString('\n')
fmt.Println(remaining)
}
Результат выполнения кода:
"Discarded: 2"
"cde"
Метод Buffered
Метод Buffered возвращает количество байтов, которые
в настоящее время находятся в буфере и доступны для чтения.
Это позволяет контролировать состояние буфера и принимать
решения о дальнейших действиях:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
data := "abcde"
reader := bufio.NewReader(strings.NewReader(data))
fmt.Println("Buffered:", reader.Buffered())
reader.ReadByte()
reader.ReadByte()
fmt.Println("Buffered after reads:", reader.Buffered())
}
Результат выполнения кода:
"Buffered: 5"
"Buffered after reads: 3"
Смотрите также
-
тип
bufio.Writer,
который предоставляет буферизированную запись данных -
тип
bufio.Scanner,
который удобен для построчного чтения данных -
функцию
bufio.NewReader,
которая создает новый буферизированный ридер -
метод
bufio.Reader.ReadString,
который читает данные до указанного разделителя