- Работа с файлами
- Текстовые файлы
- Структура текстового файла
- Машинное представление
- Пара слов о кодировках
- Популярные кодировки
- Популярные кодировки
- Работа с текстовыми файлами
- Открытие и закрытие файла
- Работа с файлом через with
- Чтение файла
- Чтение в список строк
- Чтение файла построчно
- Перемещение по файлу
- Открытие файла на запись
- Запись в файл
- Двоичные файлы
- Чтение и запись
- Чтение и запись Python объектов
- Чтение и запись числовых массивов
- Некоторые форматы
- Чтение и запись С-структур
- Некоторые форматы »struct»
- Файлы отображенные в память
- Псевдофайлы
- Сводная таблица методов файлов
- Особые файлы
- Что еще нужно знать о файлах
- Как прочитать файл построчно в Python
- Пример 1: Чтение файла построчно функцией readline()
- Как использовать функцию file.readline()
- Пример 2: Чтение строк как список функцией readlines()
- Пример 3: Считываем файл построчно из объекта File
Работа с файлами
В зависимости от того, с какими опциями открыт файл в Python он может быть или текстовым (из него будут читаться строки str ) или двоичным (из него будут читаться байтовые строки bytes ).
Текстовые файлы
Структура текстового файла
Машинное представление
00000000 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a d0 9f d1 |Hello world. | 00000010 80 d0 b8 d0 b2 d0 b5 d1 82 20 d0 bc d0 b8 d1 80 |. . | 00000020 21 0a |!.|
Пара слов о кодировках
Однобайтовые (кодовые страницы, например, CP1251): один байт соответствует одному символу. Диапазон 0-127 одинаков для всех кодовых страниц и включает символы латинского алфавита, знакам препинания, цифры, основные знаки математических действий некоторые непечатные символы. Диапазон 127-255 свой для каждой кодировки.
Популярные кодировки
utf8 — стандарт для современных Unix-like систем. Кодировка текстовых файлов в Python по умолчанию. Кодировка исходного кода на Python по умолчанию.
Популярные кодировки
Еще Windows, Unix и Mac отличаются символами конца строки в текстовых файлах:
Работа с текстовыми файлами
Открытие и закрытие файла
# Открытие на чтение (текст) fobj = open("test.txt") # Открытие на чтение в заданной кодировке (текст) fobj = open("test.txt", encoding="utf8") fobj = open("test.txt", encoding="utf8", newline="\n") # Работа с файлом # Закрытие fobj.close()
Проблема: если при работе с файлом возникнет исключение, то файл может останется незакрытым до завершения работы программы.
Работа с файлом через with
with open("test.txt") as fobj: # Работа с файлом
Преимущества: если при работе с файлом возникнет исключение, то он все равно будет закрыт.
Проблема: рост уровня вложенности.
Чтение файла
fobj = open("test.txt") # Прочесть 5 байт s = fobj.read(5) # s == 'Hello' # Прочесть еще 5 байт s = fobj.read(5) # s == ' worl' # Прочесть файл до конца s = fobj.read() # s == 'd!\nПривет мир!\n'
Чтение в список строк
fobj = open("test.txt") # Прочесть файл sa = fobj.readlines() # sa == ['Hello world!\n','Привет мир!\n'] fobj.close()
Преимущества: Можно обращаться к отдельным строкам.
Недостатки: Файл приходится целиком загружать в память.
Чтение файла построчно
fobj = open("test.txt") for line in fobj: # line — текущая строка # line[-1] == '\n' print(line) fobj.close()
Преимущества: В каждый момент времени в память загружена только одна строка.
Недостатки: Некоторые алгоритмы обработки файлов трудно реализовать.
Перемещение по файлу
По любому файлу (текстовому или двоичному) можно перемещаться по номеру байта. (осторожнее с Unicode, если номер окажется посередине многобайтового символа — будет ошибка).
fobj = open("test.txt") s = fobj.read() # s == 'Hello world!\nПривет мир!\n' #Получить текущее положение в файле (в байтах) ps = fobj.tell() #ps == 34 #Перейти на заданное положение в файле (в байтах) fobj.seek(13) s = fobj.read(5) # s == 'Приве' # Перейти в начало fobj.seek(0) s = fobj.read() # s == 'Hello world!\nПривет мир!\n' fobj.close()
Открытие файла на запись
По умолчанию файлы открываются только на чтение.
Для записи в файл его нужно открыть с соответствующей опцией (второй аргумент open ), которая по традиции обозначается буквой. Если файл не существует, он будет создан, если существует, то возможны варианты.
Опция | Режим | Текущая позиция чтения/записи |
---|---|---|
пусто или r | Только чтение | начало |
w | Запись, файл обрезается до пустого | начало |
r+ | Чтение и запись, файл не обрезается | начало |
a | Запись, файл не обрезается | конец |
a+ | Чтение и запись, файл не обрезается | конец |
Запись в файл
fobj = open("test.txt", "w") wbc = fobj.write("Hello world!\n") # wbc == 13 fobj.close()
fobj = open("test.txt", "r+") content = fobj.read() wbc = fobj.write("Hello world!\n") # wbc == 13 wt = fobj.tell() # wt == 26 fobj.close()
Двоичные файлы
Работа с двоичным файлом аналогична работе с текстовым, однако меняются опции открытия файла. И читать/писать придется объекты типа bytes , а не str .
Опция | Режим | Текущая позиция чтения/записи |
---|---|---|
b или rb | Только чтение | начало |
wb | Запись, файл обрезается до пустого | начало |
rb+ | Чтение и запись, файл не обрезается | начало |
ab | Запись, файл не обрезается | конец |
ab+ | Чтение и запись, файл не обрезается | конец |
Чтение и запись
fobj = open("test.txt", "ab+") ds = "Привет мир!\n" dbytes = ds.encode('utf8') # dbytes == b'\xd0\x9f\xd1\x80\xd0. wbc = fobj.write(dbytes) # wbc == 21 fobj.seek(0) dbs = fobj.read(24) #dbs == b'Hello world!\nHello world!\n\xd0\x9f\xd1. len(dbs) == 24 # True fobj.close()
Чтение и запись Python объектов
Самый простой способ сохранить структурированные данные в Python — воспользоваться модулем pickle стандартной библиотеки.
import pickle sdata = fobj = open('data.pickle', 'wb') pickle.dump(sdata, fobj) fobj.close() fobj.open('data.pickle', 'rb') tdata = pickle.load(fobj) fobj.close() print(tdata) #
Достоинства: Простота. Сохраняет практически любой Python объект.
Недостатки: Только для Python. Небезопасно с точки зрения обмена данными.
Чтение и запись числовых массивов
Для работы с массивами чисел в заданном машинном формате в Python есть класс array .
import array ar = array.array('f', [2.0, 4.5, 3.3]) fobj = open('array.dat', 'wb') ar.tofile(fobj) fobj.close() ar2 = array.array('f') fobj = open('array.dat', 'rb') ar2.fromfile(fobj, 3) fobj.close() print(ar2) #array('f', [2.0, 4.5, 3.299999952316284])
Некоторые форматы
Формат | C-тип | Python-тип | Размер элемента в байтах |
---|---|---|---|
b | signed char | int | 1 |
B | unsigned char | int | 1 |
l | signed long | int | 4 |
L | unsigned long | int | 4 |
f | float | float | 4 |
d | double | float | 8 |
Достоинства: Простота. Переносимость.
Недостатки: Можно сохранять только массивы чисел.
Чтение и запись С-структур
Для работы со структурами данных C в Python есть модуль struct и его чуть более функциональный товарищ rawutil pip .
import struct st = struct.Struct('10sIIxBB') data = st.pack(b"Hello",2,3,19,19) # data == b'Hello\x00\x00\x00\x00\x00. fobj = open('struct.dat', 'wb') fobj.write(data) fobj.close() fobj = open('struct.dat', 'rb') td = fobj.read() fobj.close() values = st.unpack(td) print(values) # (b'Hello\x00\x00\x00\x00\x00', 2, 3, 19, 19)
Если структура данных сложная, но есть ее описание на С, то можно воспользоваться модулем cffi pip .
Некоторые форматы »struct»
Управление порядком байт < — little-endian, >— big-endian.
Формат | C-тип | Python-тип | Размер элемента в байтах |
---|---|---|---|
x | — | — | 1 |
b | signed char | int | 1 |
B | unsigned char | int | 1 |
i | int | int | 4 |
I | unsigned int | int | 4 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | bytes | 1 |
Недостатки: Нужно вручную описывать формат структур, думать о порядке байт и выравнивании.
Файлы отображенные в память
Есть возможность работать с файлом, как с массивом байтов не загружая его в память полностью. Для этого используется отображения файла в память.
import mmap fobj = open("hello.txt", "r+b") # Создаем отображенный файл: # Первый аргумент - дескриптор заранее открытого файла # Второй - начальное положение в байтах (можно отобразить не весь файл) mapobj = mmap.mmap(fobj.fileno(), 0) # Работаем с файлом как с массивом байтов print(mapobj[:5]) # prints b"Hello" mapobj[6:] = b" world!\n" mapobj.close()
Также файл отображенный на память поддерживает стандартные методы для работы с файлами, напрмер read и write .
Псевдофайлы
С точки зрения Python файлы это просто объекты имеющие определенные методы.
В Python есть классы объекты которых выглядят, как утки файлы, но файлами не являются. Например StringIO и BytesIO из модуля io стандартной библиотеки.
import io fobj = io.StringIO() fobj.write('First line.\n') fobj.seek(5) s = fobj.read() # s == ' line.\n' as = fobj.getvalue() # as == 'First line.\n' fobj.close()
Сводная таблица методов файлов
Метод | Действие | Возвращает |
---|---|---|
read() | Читает файл от текущей позиции до конца | str / bytes |
read(n) | Читает n символов или байт | str / bytes |
readlines() | Читает текстовый файл от текущей позиции до конца, разбивает результат по os.linesep | str / bytes |
write(x) | Записывает в файл с текущей позиции str / bytes , возвращает число записанных символов / байт | int |
tell() | Текущее положение в файле всегда в байтах | int |
seek(n) | Перемещается на позицию n в файле всегда в байтах, возвращает позицию на которую удалось переместиться | int |
flush() | Записывает сбрасывает буфер на диск | None |
close() | Закрывает файл | None |
Особые файлы
При запуске скрипта автоматически открываются 3 файла доступных в модуле sys :
Файл | Тип | Смысл |
---|---|---|
sys.stdout | w | вывод в консоль |
sys.stdout.buffer | wb | вывод в консоль |
sys.stderr | w | сообщения об ошибках |
sys.stderr.buffer | wb | сообщения об ошибках |
sys.stdin | r | ввод с консоли |
sys.stdin.buffer | rb | ввод с консоли |
Такие операции как print , input сводятся к работе с этими файлами.
Что еще нужно знать о файлах
По умолчанию запись в файл производится не в момент write , а в момент, когда накопится достаточно данных для записи. Для того, чтобы выполнить запись немедленно есть метод flush() .
Как прочитать файл построчно в Python
Существует много способов чтение из файла построчно в Python. Вы можете считать строки в список или обращаться к каждой из строк в цикле при помощи итератора или вызова функции объекта file.
В этом руководстве мы научимся считывать файл построчно, используя функции readline() , readlines() и объект файла на примерах различных программ.
Пример 1: Чтение файла построчно функцией readline()
В этом примере мы будем использовать функцию readline() для файлового объекта, получая каждую строку в цикле.
Как использовать функцию file.readline()
Следуйте пунктам приведенным ниже для того, чтобы считать файл построчно, используя функцию readline() .
- Открываем файл в режиме чтения. При этом возвращается дескриптор файла.
- Создаём бесконечный цикл while.
- В каждой итерации считываем строку файла при помощи readline() .
- Если строка не пустая, то выводим её и переходим к следующей. Вы можете проверить это, используя конструкцию if not . В противном случае файл больше не имеет строк и мы останавливаем цикл с помощью break .
# получим объект файла file1 = open("sample.txt", "r") while True: # считываем строку line = file1.readline() # прерываем цикл, если строка пустая if not line: break # выводим строку print(line.strip()) # закрываем файл file1.close
Привет! Добро пожаловать на PythonRu. Удачи в обучении!
Пример 2: Чтение строк как список функцией readlines()
Функция readlines() возвращает все строки файла в виде списка. Мы можем пройтись по списку и получить доступ к каждой строке.
В следующей программе мы должны открыть текстовый файл и получить список всех его строк, используя функцию readlines() . После этого мы используем цикл for, чтобы обойти данный список.
# получим объект файла file1 = open("sample.txt", "r") # считываем все строки lines = file1.readlines() # итерация по строкам for line in lines: print(line.strip()) # закрываем файл file1.close
Привет! Добро пожаловать на PythonRu. Удачи в обучении!
Пример 3: Считываем файл построчно из объекта File
В нашем первом примере, мы считываем каждую строку файла при помощи бесконечного цикла while и функции readline() . Но Вы можете использовать цикл for для файлового объекта, чтобы в каждой итерации цикла получать строку, пока не будет достигнут конец файла.
Ниже приводится программа, демонстрирующая применение оператора for-in, для того, чтобы перебрать строки файла.
Для демонстрации откроем файл с помощью with open. Это применимо и к предыдущим двум примерам.