Бінарні файли. Приклади роботи з бінарними файлами
У даній темі показано як можна зберігати дані в бінарних файлах без використання стандартних засобів pickle або struct мови Python.
Зміст
- 1. Поняття про бінарні файли. Представлення інформації в бінарних файлах
- 2. Запис/читання списку, що містить дійсні числа. Приклад
- 3. Запис/читання кортежу, що містить рядки символів. Приклад
- 4. Запис/читання множини, що містить дійсні числа. Приклад
- 5. Запис/читання двовимірної матриці рядків заданого розміру. Приклад
- 6. Запис/читання словника. Приклад
- 7. Копіювання одного бінарного файлу в інший
- 8. Об’єднання двох бінарних файлів
- Зв’язані теми
Пошук на інших ресурсах:
1. Поняття про бінарні файли. Представлення інформації в бінарних файлах
У мові Python є засоби для роботи з бінарними файлами. Бінарні файли використовують рядки типу bytes. Тобто, якщо здійснюється операція читання двійкових даних з файлу, то повертається об’єкт типу bytes.
Відкриття бінарного файлу здійснюється з допомогою функції open(), параметр mode якої містить символ ‘b’. Більш детально про відкриття/закриття бінарних файлів описується тут.
На відміну від текстових, бінарні файли не виконують перетворення символів кінця рядка ‘\n’.
Приклад, що демонструє особливості представлення інформації у двійкових файлах.
# Python. Робота з бінарними файлами # Відкрити двійковий файл для читання f = open('myfile1.bin', 'rb') # Отримати один рядок з бінарного файлу d = f.read() # Вивести цей рядок. # Буде отримано вивід як рядок символів print("d = ", d) # d = b'\x80\x03]q\x00(K\x01\x88G@\x07\n=p\xa3\xd7\ne.' # Якщо вивести як окремий символ, # то буде виведено код символу - як ціле число print("d[5] = ", d[5]) # d[5] = 40 print("d[0] = ", d[0]) # 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 = ", L2) # 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 = ", T2) # 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}) # Додати x до множини # 3.4. Вивести множину print("M2 = ", M2) # 3.5. Закрити файл f.close()
Результат роботи програми
M2 = {0.2, 0.8, 0.3, 1.77, 1.2}
Вигляд файлу 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, "] = ", MATRIX2[i]) i = i+1 # 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 = ", D2) # 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()
- Приклади роботи з текстовими файлами
- Модуль io. Ієрархія класів. Клас IOBase. Методи роботи з файлами
⇑