Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading and interpreting data from a binary file in Python

Tags:

I want to read a file byte by byte and check if the last bit of each byte is set:

#!/usr/bin/python  def main():     fh = open('/tmp/test.txt', 'rb')     try:         byte = fh.read(1)         while byte != "":             if (int(byte,16) & 0x01) is 0x01:                 print 1             else:                 print 0             byte = fh.read(1)     finally:         fh.close      fh.close()  if __name__ == "__main__":         main() 

The error I get is:

Traceback (most recent call last):   File "./mini_01.py", line 21, in <module>     main()   File "./mini_01.py", line 10, in main     if (int(byte,16) & 0x01) is 0x01: ValueError: invalid literal for int() with base 16: '\xaf' 

Anyone an idea? I didn't succeed using the struct and the binascii modules.

like image 263
dubbaluga Avatar asked Oct 15 '10 14:10

dubbaluga


People also ask

How do you read from a binary file in Python?

To open a file in binary format, add 'b' to the mode parameter. Hence the "rb" mode opens the file in binary format for reading, while the "wb" mode opens the file in binary format for writing. Unlike text files, binary files are not human-readable. When opened using any text editor, the data is unrecognizable.

How do you convert binary to data in Python?

First, open a file in binary write mode and then specify the contents to write in the form of bytes. Next, use the write function to write the byte contents to a binary file.


2 Answers

Try using the bytearray type (Python 2.6 and later), it's much better suited to dealing with byte data. Your try block would be just:

ba = bytearray(fh.read()) for byte in ba:     print byte & 1 

or to create a list of results:

low_bit_list = [byte & 1 for byte in bytearray(fh.read())] 

This works because when you index a bytearray you just get back an integer (0-255), whereas if you just read a byte from the file you get back a single character string and so need to use ord to convert it to an integer.


If your file is too big to comfortably hold in memory (though I'm guessing it isn't) then an mmap could be used to create the bytearray from a buffer:

import mmap m = mmap.mmap(fh.fileno(), 0, access=mmap.ACCESS_READ) ba = bytearray(m) 
like image 62
Scott Griffiths Avatar answered Sep 18 '22 06:09

Scott Griffiths


You want to use ord instead of int:

if (ord(byte) & 0x01) == 0x01: 
like image 34
nmichaels Avatar answered Sep 18 '22 06:09

nmichaels