Python: все варианты чтения файлов и их особенности
Основные режимы чтения файлов в Python
Базовый режим чтения 'r'
Функция open() с аргументом 'r' открывает файл для чтения в текстовом режиме. При использовании менеджера контекста with файл автоматически закрывается после завершения блока.
with open('example.txt', 'r') as file:
content = file.read()
print(content)режим чтения python (режимы чтения файлов в python)
Это содержимое файла example.txt
Если файл не существует, возникает исключение FileNotFoundError. Для предотвращения ошибки рекомендуется проверять существование файла или использовать блок try-except.
Типичная ошибка:
Забыть указать кодировку. На Windows текстовые файлы могут быть в кодировке cp1251, что вызывает UnicodeDecodeError. Решение: явно задать параметр encoding='utf-8' или другую нужную кодировку.
Как прочитать файл целиком одной строкой?
Метод read() возвращает всю строку из файла. Применимо для небольших файлов, умещающихся в оперативной памяти.
with open('data.txt', 'r') as f:
data = f.read()
Цель: получить всё содержимое для последующей обработки (поиск, замена, парсинг).
Проблема:
При чтении больших файлов read() загружает всё в память, что может привести к ошибке MemoryError. Решение: использовать построчное чтение или чтение частями.
Как прочитать файл построчно с readline?
Метод readline() считывает одну строку. Каждый последующий вызов возвращает следующую строку, пока не будет достигнут конец файла (возвращается пустая строка).
with open('lines.txt', 'r') as f:
line = f.readline()
while line:
print(line.strip())
line = f.readline()
Строка 1
Строка 2
Строка 3
Цель: обработка строк последовательно без загрузки всего файла в память. Пример: чтение логов, где каждая строка независима.
Ошибка:
Пропуск пустой строки в конце файла. readline() возвращает пустую строку, но не завершает цикл, если не проверить. Условие выхода – while line: завершится, когда line == ''. Однако если строка содержит только пробелы, она не пуста.
Как использовать итерацию по файлу для построчного чтения?
Файловый объект является итератором. Цикл for line in file автоматически считывает строки до конца файла. Это самый эффективный и читаемый способ.
with open('data.txt', 'r') as f:
for line in f:
print(line, end='')
Первая строка
Вторая строка
Третья строка
Цель: обработка больших файлов с минимальным расходом памяти, так как в каждой итерации хранится только одна строка.
Типичная ошибка:
Использование readlines() вместо итерации. readlines() загружает все строки в список, что аналогично read() по потреблению памяти.
Как прочитать файл с указанием кодировки?
Параметр encoding в open() задаёт кодировку файла. По умолчанию используется системная кодировка (часто UTF-8 на Linux/macOS, cp1251 на Windows).
with open('file_cp1251.txt', 'r', encoding='cp1251') as f:
text = f.read()
print(text)
Цель: корректное чтение файлов, созданных в других кодировках (например, старые тексты Windows).
Проблема:
Если указать неверную кодировку, возникнет UnicodeDecodeError или будут прочитаны «кракозябры». Рекомендуется заранее определить кодировку с помощью модуля chardet или locale.getpreferredencoding().
Как читать файл в бинарном режиме?
Режим 'rb' открывает файл для чтения в бинарном режиме. Данные возвращаются в виде объекта bytes. Это необходимо для нетекстовых файлов (изображения, аудио, архивы).
with open('image.png', 'rb') as f:
binary_data = f.read()
print(type(binary_data)) #
Цель: работа с бинарными данными, копирование файлов, чтение файлов с неизвестной кодировкой.
Ошибка:
Попытка декодировать бинарные данные в строку без указания кодировки. Использовать binary_data.decode('utf-8') только если файл действительно текстовый.
Как читать файл частями фиксированного размера?
Метод read(size) считывает не более size байт или символов. Это полезно для потоковой обработки больших файлов.
with open('bigfile.dat', 'rb') as f:
chunk = f.read(1024)
while chunk:
process(chunk)
chunk = f.read(1024)
Цель: обработка файлов, которые не помещаются в оперативную память. Например, чтение видеофайлов или дампов баз данных.
Проблема:
Неправильный размер чанка: слишком малый приводит к большому количеству операций ввода-вывода, слишком большой может вызвать проблемы с памятью. Оптимальный размер – степень двойки (4KB, 8KB, 64KB).
Расширенные примеры чтения файлов
Пример 1. Чтение файла с явным указанием кодировки и обработкой ошибок
При чтении текстового файла с неизвестной кодировкой применяется блок try-except и возможное резервное кодирование.
def read_file_safe(filename):
encodings = ['utf-8', 'cp1251', 'latin-1']
for enc in encodings:
try:
with open(filename, 'r', encoding=enc) as f:
return f.read()
except UnicodeDecodeError:
continue
raise ValueError(f'Не удалось прочитать файл {filename} с известными кодировками')
content = read_file_safe('text.txt')
print(content[:200])
Первые 200 символов файла, корректно декодированные
Пример 2. Использование seek и tell для произвольного доступа
Метод seek(offset, whence) перемещает указатель чтения, tell() возвращает текущую позицию. Позволяет читать файл не последовательно.
with open('data.txt', 'r') as f:
f.seek(10) # переместиться на 10-й символ от начала
print(f.read(5)) # прочитать 5 символов
print(f.tell()) # позиция после чтения
f.seek(0, 2) # переместиться в конец файла (whence=2)
print(f.tell()) # размер файла
символы с 10 по 14
15 (позиция после чтения)
размер_файла_в_байтах
Пример 3. Чтение CSV файла без модуля csv (построчная обработка)
Разделение строки по запятой, обработка заголовка.
with open('data.csv', 'r') as f:
header = f.readline().strip().split(',')
print('Заголовки:', header)
for line in f:
row = line.strip().split(',')
print(row)
Заголовки: ['Name', 'Age', 'City']
['Alice', '30', 'NYC']
['Bob', '25', 'LA']
Пример 4. Чтение JSON файла построчно (NDJSON)
Файл содержит одну JSON-строку на строку.
import json
with open('data.ndjson', 'r') as f:
for line in f:
obj = json.loads(line)
print(obj['id'])
1
2
3
Пример 5. Чтение большого файла по частям с прогресс-баром
Используется для визуализации процесса загрузки.
import os
file_size = os.path.getsize('bigfile.bin')
read_so_far = 0
with open('bigfile.bin', 'rb') as f:
while True:
chunk = f.read(8192)
if not chunk:
break
read_so_far += len(chunk)
progress = read_so_far / file_size * 100
print(f'Прочитано {progress:.1f}%')
# обработка chunk
Прочитано 12.5%
Прочитано 25.0%
...
Прочитано 100.0%
Пример 6. Сравнение производительности методов чтения
Замер времени для файла размером ~1 GB.
import time
filename = 'large_file.txt'
# read()
start = time.time()
with open(filename, 'r') as f:
f.read()
print('read():', time.time()-start)
# readlines()
start = time.time()
with open(filename, 'r') as f:
f.readlines()
print('readlines():', time.time()-start)
# итерация по строкам
start = time.time()
with open(filename, 'r') as f:
for line in f:
pass
print('for line:', time.time()-start)
read(): 0.45
readlines(): 0.44
for line: 0.41
Итерация по строкам обычно чуть быстрее и использует меньше памяти.
Пример 7. Чтение файла в бинарном режиме и преобразование в int
Для файлов, содержащих бинарные структуры (например, целые числа).
import struct
with open('ints.bin', 'rb') as f:
# читаем 4 байта как signed integer
value = struct.unpack('i', f.read(4))[0]
print(value)
42