Буферизованные средства чтения
Эффективно читайте с помощью bufio
«Буферизованные средства чтения» — бесплатный урок Go Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Зачем нужны буферизованные чтения
Чтение из файла или сети по одному байту вызывает системный вызов каждый раз. Это медленно.
Пакет bufio оборачивает средство чтения и считывает данные большими блоками во внутренний буфер, обслуживая небольшие операции чтения из этого буфера.
- Меньше системных вызовов
- Гораздо выше скорость при множестве небольших операций чтения
Создание bufio.Reader
Оберните любое средство чтения io.Reader с помощью bufio.NewReader. Здесь мы оборачиваем strings.Reader.
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
r := bufio.NewReader(strings.NewReader("Hello, Go!"))
fmt.Printf("buffered reader ready: %T\n", r)
}Чтение Bytes
ReadByte возвращает следующий отдельный байт. Он берётся из буфера, а не в результате нового системного вызова.
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
r := bufio.NewReader(strings.NewReader("Go"))
b1, _ := r.ReadByte()
b2, _ := r.ReadByte()
fmt.Printf("%c%c\n", b1, b2)
}ReadString до разделителя
ReadString(delim) читает до первого вхождения байта-разделителя и возвращает всё, включая разделитель.
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
r := bufio.NewReader(strings.NewReader("first,second,third"))
part, _ := r.ReadString(',')
fmt.Printf("%q\n", part)
}Предварительный просмотр
Peek(n) возвращает следующие n байт, не извлекая их из буфера. Это удобно, чтобы определить способ разбора до принятия решения.
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
r := bufio.NewReader(strings.NewReader("HTTP/1.1"))
head, _ := r.Peek(4)
fmt.Printf("starts with: %s\n", head)
}Размер буфера
bufio.NewReaderSize(r, size) задаёт ёмкость буфера. Больший буфер означает меньше операций чтения из нижележащего источника, но требует больше памяти.
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
r := bufio.NewReaderSize(strings.NewReader("data"), 4096)
fmt.Println("buffer size:", r.Size())
}ReadLine и ReadString
ReadString('\n') сохраняет символ новой строки; многие анализаторы предпочитают удалять его. Scanner (в следующем уроке) делает это автоматически.
Используйте ReadString, когда нужен полный контроль над разделителями.
Обработка io.EOF
Когда нижележащий поток исчерпан, методы чтения возвращают io.EOF. Всегда проверяйте это значение, чтобы знать, когда остановиться.
package main
import (
"bufio"
"fmt"
"io"
"strings"
)
func main() {
r := bufio.NewReader(strings.NewReader("ab"))
for {
c, err := r.ReadByte()
if err == io.EOF {
break
}
fmt.Printf("%c", c)
}
fmt.Println()
}ReadRune для Unicode
ReadRune декодирует полноценную руническую последовательность UTF-8, которая может занимать несколько байт. Используйте его для текста с символами, отличными от ASCII.
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
r := bufio.NewReader(strings.NewReader("héllo"))
for {
ru, _, err := r.ReadRune()
if err != nil {
break
}
fmt.Printf("%c ", ru)
}
fmt.Println()
}Чтение до завершения
Распространённый шаблон: выполняйте цикл с ReadString до EOF, чтобы обрабатывать поток построчно, сохраняя точный контроль.
package main
import (
"bufio"
"fmt"
"io"
"strings"
)
func main() {
r := bufio.NewReader(strings.NewReader("a\nb\nc\n"))
for {
line, err := r.ReadString('\n')
fmt.Print("got: " + line)
if err == io.EOF {
break
}
}
}Когда использовать bufio.Reader
- Для оборачивания медленных источников (файлов, сокетов)
- При множестве небольших операций чтения
- Когда нужно просматривать данные заранее или читать по разделителю либо руне
Для простого построчного сканирования предпочтительнее bufio.Scanner (в следующем уроке).
Быстрая проверка
Проверьте, насколько хорошо Вы поняли работу буферизованных средств чтения.
Итоги
Вы узнали, как bufio.Reader уменьшает количество системных вызовов благодаря буферизации.
NewReader/NewReaderSizeоборачивают io.ReaderReadByte,ReadRune,ReadStringизвлекают данные из буфераPeekпросматривает данные заранее, не извлекая их- Останавливайтесь при
io.EOF
Часто задаваемые вопросы
Урок «Буферизованные средства чтения» бесплатный?
Да — полный текст урока «Буферизованные средства чтения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Буферизованные средства чтения»?
Эффективно читайте с помощью bufio Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Буферизованные средства чтения»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Буферизованные средства чтения
- Сканеры
- Буферизованные средства записи
- Потоковая обработка больших файлов