A library for defining the structure of a binary file and then reading or writing it.
Project description
binaryfile
A library for defining the structure of a binary file and then reading or writing it.
import binaryfile
def png(b):
b.byteorder = 'big'
b.skip(16)
b.uint('width', 4)
b.uint('height', 4)
b.uint('depth', 1)
with open('image.png', 'rb') as fh:
data = binaryfile.read(fh, png)
print(f"Image is {data.width} pixels wide, {data.height} pixels tall, and {data.depth} bits deep.")
Getting Started
Requirements
You will need Python 3.6 or later.
Installing
Windows with Python launcher:
py -3 -m pip install binaryfile
Linux with python3-pip:
pip3 install binaryfile
How to use
If you want to read or write to a binary file, first you will need to define the file structure. You do this by writing a function that takes a single argument, which is a subclass of binaryfile.fileformat.BinarySectionBase. The file structure is then defined by calling methods on said argument:
import binaryfile
import io
# Define the file structure
def file_spec(f):
size = f.count('size', 'text', 2) # A two-byte unsigned integer
f.bytes('text', size) # A variable number of bytes
if __name__ == '__main__':
# Read the file and print the text field
with open('myfile.dat', 'rb') as file_handle:
data = binaryfile.read(file_handle, file_spec)
print(data.text.decode('utf-8'))
# Modify the text field
data.text += ' More Text!'.encode('utf-8')
# Then write back to file
with open('myfile.dat', 'wb') as file_handle:
binaryfile.write(file_handle, data, file_spec)
You can break the definition into reusable sections:
def subsection_spec(f):
f.struct('position', 'fff') # Three floats, using a format string from Python's built-in struct module
def section_spec(f):
f.int('type', 1) # A one-byte signed integer
f.section('subsection1', subsection_spec) # Three floats, as specified in subsection_spec
f.section('subsection2', subsection_spec)
def file_spec(f):
f.section(f'section1', section_spec)
f.section(f'section2', section_spec)
f.section(f'section3', section_spec)
if __name__ == '__main__':
with open('myfile2.dat', 'rb') as file_handle:
data = binaryfile.read(file_handle, file_spec)
print(data.section2.subsection1.position)
And you can declare fields to be arrays and use loops:
def file_spec(f):
f.array('positions') # Declare "positions" to be an array
count = f.count('count', 'positions', 4)
for i in range(count):
f.struct('positions', 'fff') # Each time "positions" is used, it's the next element of the array
Reference
The reference documentation for this module is in the source at binaryfile/fileformat.py.
- Look at the
BinarySectionBaseclass for all the methods available when writing a specification. - Then check out the
readandwritefunctions for how to use the specification to read and write file-like objects. Thereadandwritefunctions are also available from thebinaryfilenamespace.
Configuration
Result type
By default, a file is read into a binaryfile.utils.SimpleDict, which allows you to access the fields by dot notation (e.g. foo.bar.baz). This means you cannot use names that are invalid field names in Python.
To override the result type, pass the desired type to result_type in the read call, e.g.:
binaryfile.read(fh, spec, result_type=dict)
The desired type must be a dict-like type that implements __getitem__, __setitem__ and __contains__.
Byte order
The default byte order is big-endian. You can change the endianness either by setting byteorder on the BinarySectionBase object, or in individual methods that support it.
Valid byteorders are 'big' and 'little', which is also the possible values returned by sys.byteorder.
def spec(b):
b.byteorder = 'little'
b.int('a', 4) # Little-endian
b.int('b', 4, byteorder='big') # Big-endian
b.int('c', 4) # Little-endian again
Automated tests
Setting up the environment
- Create and activate a Python virtual environment.
- From the project root, run
./setup.py developto install a binaryfile package linked to the project source into the venv.
Running the tests
Make sure that the venv is active, then run the Python files in the tests folder.
License
This project is licensed under MIT License, see LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file binaryfile-1.2.0.tar.gz.
File metadata
- Download URL: binaryfile-1.2.0.tar.gz
- Upload date:
- Size: 6.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.0 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0177dcb262c063b29dc8ebea3e8121efb67e47b1d3c60ee402a3a1a457fe3320
|
|
| MD5 |
bc6290ae4071dd2ecdb42188ccc95b99
|
|
| BLAKE2b-256 |
36edc2c630931664bc769c5b9dfc8813a02bc52192891785cd5fc4dde3c1f0c3
|
File details
Details for the file binaryfile-1.2.0-py3-none-any.whl.
File metadata
- Download URL: binaryfile-1.2.0-py3-none-any.whl
- Upload date:
- Size: 7.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.0 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c4824ae18f6721b453f7b4ea30c5952e26f5b593458a69d80e6cefba8e6e0d6
|
|
| MD5 |
27de2883bf73c5436fae94753286ea6b
|
|
| BLAKE2b-256 |
fd648fa89076f62c4d1e852f292f105b5583de6148b3938873c5810589e63f3c
|