Построчное чтение больших файлов

Reading time ~1 minute

Использовать bufio.Scanner, чтобы не загружать весь файл в память:

file, err := os.Open("large_file.txt")
if err != nil {
    log.Fatal("Произошла ошибка при открытии файла", err)
}
defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}
if err := scanner.Error(); err != nil {
    log.Fatal("Произошла ошибка чтения файла", err)
}

Здесь bufio.NewScanner создаёт объект, который умеет “читать по строкам”. Он сам заботится о разбиении потока байт на отдельные текстовые строки (по символу новой строки).

Каждый вызов scanner.Scan() читает из файла до следующей строки, возвращая её текст через scanner.Text(). В памяти хранится только одна строку за раз, а не весь файл целиком. Это позволяет обрабатывать файлы размером в сотни мегабайт даже на машинах с ограниченным объёмом ОЗУ.

Как работает буферизация?

При первом вызове scanner.Scan() bufio.Scanner запрашивает у ОС не по байту, а целый блок (обычно ~4 КБ) и кладёт его в свой внутренний буфер. Внутренний алгоритм разбивает этот блок по символам \n, отдаёт строки одну за другой и, когда буфер почти исчерпан, подгружает следующий блок

Такой подход резко сокращает число дорогостоящих обращений к диску (системных вызовов) и делает чтение больших файлов намного быстрее.

Что такое os.File

Файл — это не просто значок на рабочем столе. Это структурированный набор данных, который хранится на диске и управляется операционной си...… Continue reading