Как ставить бинарный файл на дозапись питон
Перейти к содержимому

Как ставить бинарный файл на дозапись питон

  • автор:

Как ставить бинарный файл на дозапись питон

Бинарные файлы в отличие от текстовых хранят информацию в виде набора байт. Для работы с ними в Python необходим встроенный модуль pickle . Этот модуль предоставляет два метода:

  • dump(obj, file) : записывает объект obj в бинарный файл file
  • load(file) : считывает данные из бинарного файла в объект

При открытии бинарного файла на чтение или запись также надо учитывать, что нам нужно применять режим «b» в дополнение к режиму записи («w») или чтения («r»). Допустим, надо надо сохранить два объекта:

import pickle FILENAME = "user.dat" name = "Tom" age = 19 with open(FILENAME, "wb") as file: pickle.dump(name, file) pickle.dump(age, file) with open(FILENAME, "rb") as file: name = pickle.load(file) age = pickle.load(file) print("Имя:", name, "\tВозраст:", age)

С помощью функции dump последовательно записываются два объекта. Поэтому при чтении файла также последовательно посредством функции load мы можем считать эти объекты. Консольный вывод программы:

Имя: Tom Возраст: 28

Подобным образом мы можем сохранять и извлекать из файла наборы объектов:

import pickle FILENAME = "users.dat" users = [ ["Tom", 28, True], ["Alice", 23, False], ["Bob", 34, False] ] with open(FILENAME, "wb") as file: pickle.dump(users, file) with open(FILENAME, "rb") as file: users_from_file = pickle.load(file) for user in users_from_file: print("Имя:", user[0], "\tВозраст:", user[1], "\tЖенат(замужем):", user[2])

В зависимости от того, какой объект мы записывали функцией dump, тот же объект будет возвращен функцией load при считывании файла.

Имя: Tom Возраст: 28 Женат(замужем): True Имя: Alice Возраст: 23 Женат(замужем): False Имя: Bob Возраст: 34 Женат(замужем): False

Работа с файлами

Любая программа, которая выполняется на компьютере пользователя скорее всего взаимодействует с файловой системой: умеет открывать файлы, сохранять их в своих форматах, возможно, хранит в файлах настройки.

Сегодня наши программы тоже смогут так делать!

Что такое файл?

До этого момента вся информация, с которой мы работали, хранилась исключительно в оперативной памяти — в переменных.

Но информация из оперативной пропадает при закрытии программы или перезагрузке компьютера. Что делать с данными, которые нужно хранить между запусками? Единственное решение — это хранить данные на энергонезависимом носителе — жестком диске (HDD) или твердотельном накопителе (SSD). Далее будет использоваться термин жесткий диск, хотя подразумевается любое из этих устройств.

Участок жесткого диска, у которого есть имя называется файлом.

Также, как и переменные, файлы занимают какое-то место, их размер измеряется в байтах.

Способ организации и хранения файлов на диске называется файловой системой.

Текстовые и бинарные файлы

С точки зрения прикладных программ файлы делятся на два основных типа: текстовые и бинарные. Физически оба типа файлов не отличаются и хранят в себе байты с данными, отличается лишь их интерпретация нашей программой.

В текстовых файлах хранятся текстовые данные. В зависимости от кодировки каждый символ кодируется равным числом байт.

Текстовые файлы могут иметь произвольные расширения, вам, возможно встречались .txt, .py, .html.

Текстовые файлы можно открыть в текстовом редакторе, например, в блокноте.

В бинарных файлах хранятся произвольные данные: символы, числа, дроби, но разные объекты могут кодироваться разным числом байт.

Как интерпретировать ту или иную группу байт в файле, нам говорит формат файла. Примеры бинарных файлов: .exe, .doc, .dll и тд..

Если открыть бинарный файл в блокноте, вы увидите много страшных символов — компьютер попытается интерпретировать все данные в файле как буквы.

Создаем текстовый файл

При работе с файлами всегда используется следующий алгоритм:

  • открытие файла
  • изменение или чтение файла
  • закрытие файла

Не забудьте закрыть файл, если он вам больше не нужен, иначе другие программы не смогут открыть его. Операционная система следит за тем, чтобы файлом в один момент управляла только одна программа.

Чтобы открыть файл, в питоне используется функция open(path, mode) , которая принимает путь к файлу (абсолютный или относительный) и режим. Режим — это либо чтение (read), либо запись (write), либо добавление в конец файла (append).

Если файл открыт только для чтения, то записать данные в него нельзя. Нужно закрыть его и открыть в другом режиме.

Давайте создадим текстовый файл и запишем туда небольшой текст:

file = open('new.txt', 'w') # открываем файл new.txt для записи (w) file.write("hello world! :)") # записываем строку в файл file.close() # закрываем файл

Обратите внимание: если открыть файл для записи, старые данные из него автоматически стираются.

После выполнения программы, в папке с кодом должен появиться новый файл new.txt, а в нем — строка «hello world».

Читаем текстовый файл

Аналогично записи в текстовый файл, мы можем открыть его для чтения и прочитать все его содержимое в переменную.

file = open('smiles.txt', 'r') # открываем файл smiles.txt для чтения (r) text = file.read() # считываем все содержимое файла в переменную file.close() print(text[:100])

Файл smiles.txt можно скачать тут.

Используем with

Чтобы случайно не забыть закрыть файл после окончания работы с ним, используйте обертку with . Она автоматически закроет файл, как только закончится ее область видимости.

Пример:

with open('smiles.txt', 'r') as file: text = file.read() # файл автоматически закрылся print(text[:100])

Функция open. Чтение и запись текстовых файлов в Python

Большие объемы данных хранят не в списках или словарях, а в файлах и базах данных. В этом уроке изучим особенности работы с текстовыми файлами в Python. Такие файлы рассматриваются как содержащие символы и строки.

Бывают еще байтовые (бинарные) файлы, которые рассматриваются как потоки байтов. Побайтово считываются, например, файлы изображений. Работа с бинарными файлами несколько сложнее. Нередко их обрабатывают с помощью специальных модулей Python (pickle, struct).

Функция open

Связь с файлом на жестком диске выполняется с помощью встроенной в Python функции open() . Обычно ей передают один или два аргумента. Первый – имя файла или имя с адресом, если файл находится не в том каталоге, где находится сама программа. Второй аргумент – режим, в котором открывается файл.

Обычно используются режимы чтения ( ‘r’ ) и записи ( ‘w’ ). Если файл открыт в режиме чтения, то запись в него невозможна. Можно только считывать данные. Если файл открыт в режиме записи, то в него можно только записывать данные, считывать нельзя.

Если файл открывается в режиме ‘w’ , то все данные, которые в нем были до этого, стираются. Файл становится пустым. Если не надо удалять существующие в файле данные, тогда следует использовать вместо режима записи, режим дозаписи ( ‘a’ ).

Если файл отсутствует, то открытие его в режиме ‘w’ создаст новый файл. Бывают ситуации, когда надо гарантировано создать новый файл, избежав случайной перезаписи данных существующего. В этом случае вместо режима ‘w’ используется режим ‘x’ . В нем всегда создается новый файл для записи. Если указано имя существующего файла, то будет выброшено исключение. Потери данных в уже имеющемся файле не произойдет.

Если при вызове open() второй аргумент не указан, то файл открывается в режиме чтения как текстовый файл. Чтобы открыть файл как байтовый, дополнительно к букве режима чтения/записи добавляется символ ‘b’ . Буква ‘t’ обозначает текстовый файл. Поскольку это тип файла по умолчанию, то обычно ее не указывают.

Нельзя указывать только тип файла, то есть open(«имя_файла», ‘b’) есть ошибка, даже если файл открывается на чтение. Правильно – open(«имя_файла», ‘rb’) . Только текстовые файлы мы можем открыть командой open(«имя_файла») , потому что и ‘r’ и ‘t’ подразумеваются по-умолчанию.

Функция open() возвращает объект файлового типа. Его надо либо сразу связать с переменной, чтобы не потерять, либо сразу прочитать.

Чтение файла

С помощью файлового метода read() можно прочитать файл целиком или только определенное количество байт. Пусть у нас имеется файл data.txt с таким содержимым:

one - 1 - I two - 2 - II three - 3 - III four - 4 - IV five - 5 - V

Откроем его и почитаем:

>>> f1 = open(‘data.txt’) >>> f1.read(10) ‘one — 1 — ‘ >>> f1.read() ‘I\ntwo — 2 — II\nthree — 3 — III\nfour — 4 — IV\nfive — 5 — V\n’ >>> f1.read() » >>> type(f1.read())

Сначала считываются первые десять символов. Последующий вызов read() считывает весь оставшийся текст. После этого объект файлового типа f1 становится пустым.

Заметим, что метод read() возвращает строку, и что конец строки считывается как ‘\n’ .

Для того, чтобы читать файл построчно существует метод readline() :

>>> f1 = open('data.txt') >>> f1.readline() 'one - 1 - I\n' >>> f1.readline() 'two - 2 - II\n' >>> f1.readline() 'three - 3 — III\n'

Метод readlines() считывает сразу все строки и создает список:

>>> f1 = open('data.txt') >>> f1.readlines() ['one - 1 - I\n', 'two - 2 - II\n', 'three - 3 - III\n', 'four - 4 - IV\n', 'five - 5 - V\n']

Объект файлового типа относится к итераторам. Из таких объектов происходит последовательное извлечение элементов. Элементами в данном случае являются строки-линии файла. Поэтому считывать данные из файла можно сразу в цикле без использования методов чтения:

>>> for i in open('data.txt'): . print(i) . one - 1 - I two - 2 - II three - 3 - III four - 4 - IV five - 5 - V >>>

Здесь выводятся лишние пустые строки, потому что функция print() преобразует ‘\n’ в переход на новую строку. К этому добавляет свой переход на новую строку. Создадим список строк файла без ‘\n’ :

>>> nums = [] >>> for i in open('data.txt'): . nums.append(i[:-1]) . >>> nums ['one - 1 - I', 'two - 2 - II', 'three - 3 - III', 'four - 4 - IV', 'five - 5 - V']

Переменной i присваивается очередная строка файла. Мы берем ее срез от начала до последнего символа, не включая его. Следует иметь в виду, что ‘\n’ это один символ, а не два.

Запись в файл

Запись в файл выполняется с помощью методов write() и writelines() . Во второй можно передать структуру данных:

>>> l = ['tree', 'four'] >>> f2 = open('newdata.txt', 'w') >>> f2.write('one') 3 >>> f2.write(' two') 4 >>> f2.writelines(l)

Метод write() возвращает количество записанных символов.

Закрытие файла

После того как работа с файлом закончена, важно не забывать его закрыть, чтобы освободить место в памяти. Делается это с помощью файлового метода close() . Свойство файлового объекта closed позволяет проверить закрыт ли файл.

>>> f1.close() >>> f1.closed True >>> f2.closed False

Если файл открывается в заголовке цикла ( for i in open(‘fname’) ), то видимо интерпретатор его закрывает при завершении работы цикла или через какое-то время.

Практическая работа

  1. Создайте файл data.txt по образцу урока. Напишите программу, которая открывает этот файл на чтение, построчно считывает из него данные и записывает строки в другой файл ( dataRu.txt ), заменяя английские числительные русскими, которые содержатся в списке ( [«один», «два», «три», «четыре», «пять»] ), определенном до открытия файлов.
  2. Создайте файл nums.txt , содержащий несколько чисел, записанных через пробел. Напишите программу, которая подсчитывает и выводит на экран общую сумму чисел, хранящихся в этом файле.

Примеры решения и дополнительные уроки в pdf-версии курса

X Скрыть Наверх

Python. Введение в программирование

Бинарные файлы. Примеры работы с бинарными файлами

В данной теме показано как можно сохранять данные в бинарных файлах без использования стандартных средств pickle или struct языка Python.

Поиск на других ресурсах:

1. Понятие о бинарных файлах. Представление информации в бинарных файлах

В языке Python существуют средства для работы с бинарными или двоичными файлами. Бинарные файлы используют строки типа bytes . Это значит при чтении бинарных данных из файла возвращается объект типа bytes .

Открытие бинарного файла осуществляется с помощью функции open() , параметр mode которой содержит символ ‘b’ . Более подробно об открытии/закрытии бинарных файлов описывается здесь .

В отличие от текстовых, бинарные файлы не выполняют преобразования символов конца строки ‘\n’ .

Пример, демонстрирующий особенности представления информации в бинарных файлах.

# Python. Работа с бинарными файлами # Открыть бинарный файл для чтения f = open('myfile1.bin', 'rb') # Получить одну строку из бинарного файла d = f.read() # Вывести эту строку. # Будет получен вывод в виде строки символов print("d color: #ff0000;"># d = b'\x80\x03]q\x00(K\x01\x88G@\x07\n=p\xa3\xd7\ne.' # Если вывести как отдельный символ, # то будет выведен код символа - как целое число print("d[5] color: #ff0000;"># d[5] = 40 print("d[0] color: #ff0000;"># d[0] = 128 # Использовать функцию bin для отдельного символа print(bin(d[2])) # 0b1011101 f.close()

Результат работы программы

d = b'\x80\x03]q\x00(K\x01\x88G@\x07\n=p\xa3\xd7\ne.' d[5] = 40 d[0] = 128 0b1011101

На основании примера выше можно сделать следующие выводы:

  • строка бинарных данных выводится как строка;
  • отдельный символ (элемент) бинарных данных представлен в виде 8-битных целых чисел.
2. Запись/чтение списка, который содержит вещественные числа. Пример
# Бинарные файлы. Запись/чтение списка вещественных чисел # 1. Заданный список вещественных чисел L = [1.5, 2.8, 3.3] # 2. Запись файла # 2.1. Открыть файл для записи f = open('myfile3.bin', 'wb') # 2.2. Обход списка и запись данных в файл for item in L: # добавить символ '\n', чтобы можно было распознать числа s = str(item) + '\n' # Метод encode() - конвертирует строку в последовательность байт bt = s.encode() f.write(bt) # метод write() - запись в файл # 2.3. Закрыть файл f.close(); # 3. Считать список из бинарного файла 'myfile3.bin' # 3.1. Создать пустой список L2 = [] # 3.2. Открыть файл для чтения f = open('myfile3.bin', 'rb') # 3.3. Обход строк файла, конвертирование и добавление в список L2 for ln in f: x = float(ln) # взять число L2 = L2 + [x] # Добавить число к списку # 3.4. Вывести список print("L2 color: #ff0000;"># L2 = [1.5, 2.8, 3.3] # 3.5. Закрыть файл f.close();

Результат работы программы

L2 = [1.5, 2.8, 3.3]
3. Запись/чтение кортежа, содержащего строки символов. Пример

В данном примере строки символов в бинарном файле разделяются символом ‘\n’ . Таким образом, можно записывать и читать информацию без потери ее структуры.

# Бинарные файлы. Запись/чтение кортежа, содержащего строки символов # 1. Заданный кортеж со строками T = ( 'abc', 'def', 'ghi', 'jk lmn') # 2. Запись кортежа T в файл 'myfile5.bin' # 2.1. Открыть файл для записи f = open('myfile5.bin', 'wb') # 2.2. Цикл обхода кортежа for item in T: bt = (item + '\n').encode() # конвертировать (str + '\n') => bytes f.write(bt) # записать bt в файл # 2.3. Закрыть файл f.close(); # 3. Считать кортеж из бинарного файла 'myfile5.bin' # 3.1. Открыть файл для чтения f = open('myfile5.bin', 'rb') # 3.2. Новый кортеж T2 = () # 3.3. Прочитать данные из файла for line in f: s = line.decode() # конвертировать bytes=>str s = s[:-1] # Убрать последний символ T2 = T2 + (s,) # Добавить строку s к кортежу # 3.4. Вывести кортеж print("T2 color: #ff0000;"># 3.5. Закрыть файл f.close();

Результат работы программы

T2 = ('abc', 'def', 'ghi', 'jk lmn')
4. Запись/чтение множества, содержащего вещественные числа. Пример

Множество, которое содержит только однотипные объекты можно записать в файл. В данном примере записывается множество вещественных чисел.

# Бинарные файлы. Запись/чтение множества, # которое содержит вещественные числа # 1. Заданное множество M = < 0.2, 0.3, 0.8, 1.2, 1.77 ># 2. Запись множества M в файл 'myfile6.bin' # 2.1. Открыть файл для записи f = open('myfile6.bin', 'wb') # 2.2. Цикл обхода множества for item in M: s = str(item) + '\n' # конвертировать float=>str + '\n' bt = s.encode() # конвертировать str=>bytes f.write(bt) # записать bt в файл # 2.3. Закрыть файл f.close(); # 3. Считать множество из бинарного файла 'myfile6.bin' # 3.1. Открыть файл для чтения f = open('myfile6.bin', 'rb') # 3.2. Новое множество M2 = set() # 3.3. Прочитать данные из файла for line in f: x = float(line) # конвертировать bytes=>x M2 = M2.union() # Добавить x к множеству # 3.4. Вывести множество print("M2 color: #ff0000;"># 3.5. Закрыть файл f.close()

Результат работы программы

Вид файла myfile6.bin

0.2 0.8 1.77 0.3 1.2
5. Запись/чтение двумерной матрицы строк заданного размера. Пример

В примере матрица представлена в виде списка.

# Бинарные файлы. Запись/чтение матрицы, которая содержит строки # 1. Заданная матрица строк размером 3*4 MATRIX = [ [ 'aa', 'ab', 'ac', 'ad'], [ 'ba', 'bb', 'bc', 'bd'], [ 'ca', 'cb', 'cc', 'cd'] ] # 2. Запись матрицы MATRIX в файл 'myfile7.bin' # 2.1. Открыть файл для записи f = open('myfile7.bin', 'wb') # 2.2. Сначала записать размер матрицы m = 3 n = 4 # конвертировать m, n в строчный тип str sm = str(m) + '\n' sn = str(n) + '\n' # конвертировать строку str в bytes bm = sm.encode() bn = sn.encode() # записать размеры матрицы в файл f.write(bm) f.write(bn) # 2.3. Цикл обхода матрицы for row in MATRIX: # здесь нужно просто записать строки с символом '\n' for item in row: item = item + '\n' bt = item.encode() # str=>bytes f.write(bt) # записать bt в файл # 2.3. Закрыть файл f.close(); # 3. Считать матрицу из бинарного файла 'myfile7.bin' # 3.1. Открыть файл для чтения f = open('myfile7.bin', 'rb') # 3.2. Новая матрица MATRIX2 = [] # 3.3. Прочитать данные из файла # 3.3.1. Сначала прочитать размер s = f.readline() m2 = int(s) s = f.readline() n2 = int(s) # 3.3.2. Цикл чтения строк и создание матрицы размером m2*n2 i = 0 while i < m2: # m2 строк в матрице row = [] # одна строка списка j = 0 while j < n2: bs = f.readline() # прочитать один элемент типа bytes s = bs.decode() # конвертировать bytes=>str s = s[:-1] # убрать '\n' row += [s] # добавить к списку j = j+1 MATRIX2 += [row] # добавить одну строку списка к матрице i = i+1 # 3.4. Вывести новую матрицу i = 0 while i < m2: print("MATRIX2[", i, "] color: #ff0000;"># 3.5. Закрыть файл f.close()

Результат работы программы

MATRIX2[ 0 ] = ['aa', 'ab', 'ac', 'ad'] MATRIX2[ 1 ] = ['ba', 'bb', 'bc', 'bd'] MATRIX2[ 2 ] = ['ca', 'cb', 'cc', 'cd']

Вид файла myfile7.txt

3 4 aa ab ac ad ba bb bc bd ca cb cc cd
6. Запись/чтение словаря. Пример

Пусть задан некоторый словарь, который нужно записать в бинарный файл.

# Бинарные файлы. Запись/чтение словаря # 1. Заданный словарь. Пары типа str:int D = < 'One':1, 'Two':2, 'Three':3, 'Four':4 > # 2. Запись словаря D в файл 'myfile8.bin' # 2.1. Открыть файл для записи f = open('myfile8.bin', 'wb') for key in D: # обход словаря # взять значение value value = D[key] # Записать последовательно key, затем value svalue = str(value) + '\n' # сначала конвертировать value в строку skey = key + '\n' # к строке key добавить '\n' # Конвертировать key:svalue из строки в bytes b_key = skey.encode() b_svalue = svalue.encode() # записать b_key, b_svalue в файл f.write(b_key) f.write(b_svalue) # 2.3. Закрыть файл f.close(); # 3. Считать словарь из бинарного файла 'myfile8.bin' # 3.1. Открыть файл для чтения f = open('myfile8.bin', 'rb') # 3.2. Новый словарь, который будет прочитан из файла D2 = dict() # 3.3. Прочитать весь файл сразу b_strings = f.readlines() # b_strings - список строк типа bytes # 3.4. Обойти список b_strings. # Сначала читается ключ, затем значение и т.д. fkey = True # если True, то читается ключ, иначе читается значение for item in b_strings: if fkey: # проверка, если читается ключ skey = item.decode() # конвертировать bytes=>str key = skey[:-1] # убрать '\n' fkey = False else: svalue = item.decode() # конвертировать bytes=>str value = int(svalue) # конвертировать str=>int D2[key] = value # добавить к словарю fkey = True # указать, что на следующей итерации будет ключ # 3.5. Вывести словарь print("D2 color: #ff0000;"># 3.6. Закрыть файл f.close()

Результат работы программы

D2 = 'One': 1, 'Two': 2, 'Three': 3, 'Four': 4>

Вид файла myfile8.txt

One 1 Two 2 Three 3 Four 4
7. Копирование одного бинарного файла в другой
# Бинарные файлы. Копирование файлов # 1. Открыть файлы f1 = open('myfile8.bin', 'rb') # файл - источник, открывается для чтения f2 = open('copyfile8.bin', 'wb') # файл - копия # 2. Считать файл f1 в список строк bstrings bstrings = f1.readlines() # 3. Записать список строк bstrings в файл f2 f2.writelines(bstrings) # 4. Закрыть файлы f1.close() f2.close()
8. Объединение двух бинарных файлов. Пример

В примере реализована операция объединения двух файлов в результирующий третий файл. Сначала данные с файлов-источников считываются в списки. Затем происходит конкатенация этих списков и запись результирующего списка в файл результата.

# Объединение файлов myfile1.bin+myfile2.bin => myfile3.bin # 1. Открыть файлы для чтения f1 = open('myfile1.bin', 'rb') f2 = open('myfile2.bin', 'rb') # 2. Считать файлы в списки L1, L2 L1 = f1.readlines() L2 = f2.readlines() # 3. Объединить списки L3 = L1 + L2 # 4. Закрыть файлы myfile1.bin, myfile2.bin f1.close() f2.close() # 5. Открыть файл myfile3.bin для записи f3 = open('myfile3.bin', 'wb') # 6. Записать строки в файл f3.writelines(L3) # 7. Закрыть результирующий файл f3.close()

Связанные темы

  • Файлы. Общие понятия. Открытие/закрытие файла. Функции open() , close()
  • Примеры работы с текстовыми файлами

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *