====== Двоичные форматы ======
===== Архивы =====
В стандартной библиотеке Python есть модули для работы с ''.zip'' — ''zipfile'', для прочих открытых форматов архивов существует обертка к библиотеке [[https://pypi.python.org/pypi/libarchive|libarchive]][pip].
==== Работа с zip архивами через zipfile ====
''.zip'' архив состоит из сжатых (одним из 4 алгоритмов) файлов, к каждому из которых можно обратиться зная его уникальное имя (включающее путь), это имя и используется при распаковке (при необходимости создаются соответствующие папки).
==== Чтение ====
import zipfile
zobj = zipfile.ZipFile('test.zip')
lns = obj.namelist()
# lns == ['data/test1.txt', 'data/test2.txt']
fobj = zobj.open('data/file.txt')
# Файл всегда открывается в режиме binary!
s = fobj.read()
#s == b'Test zip file content'
fobj.close()
zobj.close()
==== Запись ====
Поддерживаются опции ''w'' — перезапись архива, ''a'' — дополнение архива (если архива нет, то он будет создан) и ''x''— дополнение архива (если архива нет, то будет выброшено исключение).
import zipfile
zobj = zipfile.ZipFile('test.zip', 'a')
zobj.writestr('test.txt', b'Testing data', zipfile.ZIP_DEFLATED)
zobj.close()
Флаг ''zipfile.ZIP_DEFLATED'' необходим, иначе файл будет добавлен в архив без сжатия.
В архиве ''.zip'' нельзя создать пустую папку и нельзя сохранить атрибуты папки. Файл из архива ''.zip'' нельзя удалить, изменить или переименовать.
Кроме того ''zipfile'' позволяет извлекать файлы из архива (''extract'', ''extractall''), и добавлять их в архив по имени файла (''write''). См. [[https://docs.python.org/3/library/zipfile.html|документацию]].
===== Изображения =====
Обработка изображений дело ресурсоемкое, поэтому библиотеки Python для работы с картинками обычно имеют высокоуровневый интерфейс, под которым прячется начинка на C. Рассмотрим работу с картинками на примере библиотеки ''Pillow''[pip].
Библиотека загружает и хранит изображение в памяти целиком в одном из поддерживаемых типов массивов. Вот некоторые популярные типы массивов:
^ Тип ^ Байт на пиксель ^ Описание ^
| ''1'' | 1 | Монохромное изображение |
| ''L'' | 1 | В оттенках серого |
| ''RGB'' | 3 | Цветное изображение без прозрачности |
| ''RGBA'' | 4 | Цветное изображение c прозрачностью |
| ''HSV'' | 3 | Кодирование Тон-Яркость-Значение |
==== Чтение ====
Поддерживаемых форматов [[https://pillow.readthedocs.io/en/4.3.x/handbook/image-file-formats.html|очень много]].
from PIL import Image
# Открытые файла
im = Image.open("test.png")
im.load() # Отложенное чтение
# Создание нового изображения
im = Image.new("RGB", (100,100))
# Создание изображения из массива
im = Image.frombytes("L", (100,100), data)
==== Рисование ====
from PIL import Image, ImageDraw, ImageFont
im = Image.open("test.png")
# Создание объекта для рисования
draw = ImageDraw.Draw(im)
# Рисование
draw.line((0, 0) + im.size, fill=128)
font = ImageFont.truetype("arial.ttf", 15)
draw.text((40,40),"Привет!",font=font)
# Размер изображения
s = im.size
# s == (100, 100)
==== Запись ====
from PIL import Image
im = Image.open("test.png")
# Преобразуем тип данных
mim = im.convert('L')
# Просмотр
mim.show()
# Получаем байты в соответствии с типом
bs = mim.tobytes()
# bs = b'&\x00\x00\x00\x00\x00\x00\x00\x00...
# Сохраняем файл
mim.save("test.bmp")
Если нужно получить закодированное в заданном формате (''.bmp'', ''.jpg'') изображение, то методу ''save'' надо подложить ''io.BytesIO'' объект и указать формат через аргумент ''format''.
===== Офисные документы =====
Офисные документы можно относительно просто читать и создавать с помощью этих библиотек.
^ Расширение ^ Название ^ Модуль ^
| ''.docx'' | MS Office 2007 Word | [[https://python-docx.readthedocs.io/en/latest/|python-docx]][pip] |
| ''.xls'' | MS Office 1997 Excel | [[http://xlrd.readthedocs.io/en/latest/|xlrd]][pip], [[http://xlwt.readthedocs.io/en/latest/|xlwt]][pip] |
| ''.xlsx'' | MS Office 2007 Excel | [[https://openpyxl.readthedocs.io/en/default/|openpyxl]][pip] |
| ''.odt'' | OpenDocument Text | [[https://github.com/eea/odfpy/wiki/Introduction|odfpy]][pip] |
| ''.ods'' | OpenDocument SpreadSheet | [[https://github.com/eea/odfpy/wiki/Introduction|odfpy]][pip] |
| ''.pdf'' | Portable Document Format | [[http://www.reportlab.com/docs/reportlab-userguide.pdf|reportlab]][pip] |
| ''.svg'' | Scalable Vector Graphics | [[https://pypi.python.org/pypi/svgwrite|svgwrite]][pip] |
Однако схема «открыл → изменил → сохранил» может вызывать проблемы. В этих случаях лучше использовать API офисных пакетов.
==== Чтение электронных таблиц XLSX====
from openpyxl import load_workbook
wb = load_workbook("sample.xlsx")
ws = wb.active # Выбор листа
print(ws['A1'].value) # С использованием Excel нотации
print(ws.cell(1, 1).value) # По индексу сроки/столбца
for row in ws.rows: # По всем строкам на листе
print(row[0].value, row[1].value)
==== Запись электронных таблиц XLSX====
from openpyxl import Workbook
wb = Workbook()
ws = wb.active # Выбор листа
ws['A1'] = 42 # С использованием Excel нотации
ws.cell(1, 1, 42) # По индексу сроки/столбца
wb.save("sample.xlsx")
===== Чтение NetCDF4 =====
from netCDF4 import Dataset
#https://www.unidata.ucar.edu/software/netcdf/examples/sresa1b_ncar_ccsm3-example.nc
ncdata = Dataset("sresa1b_ncar_ccsm3-example.nc", format="NETCDF4")
print(ncdata.variables.keys()) # Обзор всех переменных
# Основная переменная:
print(ncdata['ua'].shape) # (1, 17, 128, 256)
# Оси:
print(ncdata['plev'].shape) # (17,)
print(ncdata['lat'].shape) # (128,)
print(ncdata['lon'].shape) # (256,)
# Чтение данных:
plev = ncdata['plev'][:]
lat = ncdata['lat'][:]
lon = ncdata['lon'][:]
ua = ncdata['ua'][:]
#Конкретная точка
print(plev[1],lat[20],lon[20],ua[0,1,20,20])
===== Что еще нужно знать о работе с двоичными форматами =====
* Структура произвольного двоичного формата обычно описывается в виде C-структур, поэтому читать такие файлы целесообразно с использованием ''cffi'', ''ctypes'' или ''struct''.
* Иногда встречаются беззаголовочные бинарные файлы. Например результаты работы регистратора.
* Формат некоторых двоичный файлов неизвествен и/или охраняется как объект авторского права.
* В идеальном случае спецификация формата известна, в этом случае практически наверняка есть открытая библиотека для работы с такими файлами.
* Некоторые форматы могут иметь собственные версии.
* Могут возникать проблемы совместимости между различными версиями программ/библиотек для чтения и записи файлов.