Package: binaryfile
binaryfileA library for defining the structure of a binary file and then reading or writing it.importbinaryfiledefpng(b):b.byteorder='big'b.skip(16)b.uint('width',4)b.uint('height',4)b.uint('depth',1)withopen('image.png','rb')asfh:data=binaryfile.read(fh,png)print(f"Image is{data.width}pixels wide,{data.height}pixels tall, and{data.depth}bits deep.")Getting StartedRequirementsYou will need Python 3.6 or later.InstallingWindows with Python launcher:py -3 -m pip install binaryfileLinux with python3-pip:pip3installbinaryfileHow to useIf 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:importbinaryfileimportio# Define the file structuredeffile_spec(f):size=f.count('size','text',2)# A two-byte unsigned integerf.bytes('text',size)# A variable number of bytesif__name__=='__main__':# Read the file and print the text fieldwithopen('myfile.dat','rb')asfile_handle:data=binaryfile.read(file_handle,file_spec)print(data.text.decode('utf-8'))# Modify the text fielddata.text+=' More Text!'.encode('utf-8')# Then write back to filewithopen('myfile.dat','wb')asfile_handle:binaryfile.write(file_handle,data,file_spec)You can break the definition into reusable sections:defsubsection_spec(f):f.struct('position','fff')# Three floats, using a format string from Python's built-in struct moduledefsection_spec(f):f.int('type',1)# A one-byte signed integerf.section('subsection1',subsection_spec)# Three floats, as specified in subsection_specf.section('subsection2',subsection_spec)deffile_spec(f):f.section(f'section1',section_spec)f.section(f'section2',section_spec)f.section(f'section3',section_spec)if__name__=='__main__':withopen('myfile2.dat','rb')asfile_handle:data=binaryfile.read(file_handle,file_spec)print(data.section2.subsection1.position)And you can declare fields to be arrays and use loops:deffile_spec(f):f.array('positions')# Declare "positions" to be an arraycount=f.count('count','positions',4)foriinrange(count):f.struct('positions','fff')# Each time "positions" is used, it's the next element of the arrayReferenceThe reference documentation for this module is in the source atbinaryfile/fileformat.py.Look at theBinarySectionBaseclass for all the methods available when writing a specification.Then check out thereadandwritefunctions for how to use the specification to read and write file-like objects. Thereadandwritefunctions are also available from thebinaryfilenamespace.ConfigurationResult typeBy default, a file is read into abinaryfile.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 toresult_typein 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 orderThe default byte order is big-endian. You can change the endianness either by settingbyteorderon theBinarySectionBaseobject, or in individual methods that support it.
Valid byteorders are 'big' and 'little', which is also the possible values returned bysys.byteorder.defspec(b):b.byteorder='little'b.int('a',4)# Little-endianb.int('b',4,byteorder='big')# Big-endianb.int('c',4)# Little-endian againAutomated testsSetting up the environmentCreate and activate aPython virtual environment.From the project root, run./setup.py developto install a binaryfile package linked to the project source into the venv.Running the testsMake sure that the venv is active, then run the Python files in thetestsfolder.LicenseThis project is licensed under MIT License, seeLICENSEfor details.