For some reason, I cannot get a simple string to be output to a binary file with python.
Here is my code:
strin = bytes(strin, '3DFILE')
dataH = struct.pack('s', strin)
outFile.write(dataH)
I'm trying to write a 3D model exporter for a game I am making with blender. can someone please help me out here, or give me an example? I get the error that string is not defined.
Python 3 strings are sequences of unicode characters. The characters are abstract, and they have no binary representation until you say what encoding should be used.
If you have binary data, you can write it to the binary file (opened with binary mode like outFile = open(filename, 'wb') ... outFile.close()) without problem. However, writing binary data to the file opened in text mode cannot be done. It was different in Python 2 where strings were actually sequences of bytes and even the open text file object did not care.
Related
This question already has answers here:
How to open and read a binary file in Python?
(3 answers)
Closed 1 year ago.
How can I get zeros and ones that make a file? For example, how can I open a file with Python and get the zeros and ones that make it up? And convert those zeros and ones again to a file?
Thanks for your help!
This question is very vague, so I will try and answer some of the possible questions I think you are asking.
How do I open a non-text file in binary mode
Some files need to have the "binary" versions of the files opened. A easier way to think of this would be opening a file in "raw" (binary) vs "plaintext" (text) mode.
Often API's that work with PDF files, and certain other extensions use this to open the files properly since they contain characters that are encoded to be unreadable, and use headers that would garble the files as plain strings.
To do this change the mode of a call to open() to any of these :
rb for reading a binary file. The file pointer is placed at the beginning of the file.
rb+ reading or writing a binary file
wb+ writing a binary file
ab+ Opens a file for both appending and reading in binary. The file pointer is at the end of the file if the file exists. The file opens in the append mode.
For example:
with open("filename.pdf", "rb") as pdf_file:
... # Do things
How do I get the binary values of individual string characters
If you are looking to open a file and get a binary association to a character you can use the ord() function combined with the bin() function:
ord("A") # 65
bin(ord("A")) # '0b1000001'
You can then loop through each character of a file and find a binary representation of each letter this way. This is often used in cryptography, like I did for this project.
If neither of those two solve your issues please clarify what you mean in the original question so I can better address it.
I am working with binary data. I have a file containing 2KB of binary data. I have used the following code to read the file and then print it. I have also tried to view the file contents using hexdump in the terminal. I am getting different outputs 1 and 2 (shown in attached screenshots) of the same file in python and hexdump. I am assuming it might be due to the encoding scheme used by python? I am very naive about working with binary data. Can anyone kindly check it and let me know the reasons for this? I also want to know if that's the correct way of reading a large binary file?
print("First File \n");
f1 = open("/data/SRAMDUMP/dataFiles/first.bin","rb")
num1 = list(f1.read())
print(num1)
f1.close()
I am assuming it might be due to the encoding scheme used by python?
There is no "encoding scheme" hexdump formats binary data as hex (two nibbles per byte), you've converted the binary contents of the file to a list which yields a list of integers (since that's what bytes are in python).
If you want to convert bytes to printable hex in Python, use the bytes.hex method. If you want something similar to hexdump, you'll need to take care of slicing, spacing and carriage-return-ing.
A slow version would simply read the file 2 bytes per 2 bytes, hex them, print them, then linebreak every 16 bytes. Python 3.8 adds formatting facilities to bytes.hex() meaning you can even more easily read bytes 16 by 16 with a separator every two, though that doesn't exactly match hexdump's format:
f = open(sys.argv[1], 'rb')
it = iter(functools.partial(f.read, 16), '')
for i, b in enumerate(it):
print(f'{16*i:07x} {b.hex(" ", 2)}')
Also beware that hexdump follows the platform's endianness by default which is... rarely what you want, and will not match your Python output. hexdump -C prints bytes in the file order.
I have the byte-code of a png-file in a string variable. How do I write it to .png file without python trying to encode it? The string is '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\n\x00\x00\x00\x07\x08\x02\x00\x00\x00\xbe\xceK4\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00DIDAT\x18Wc\xf8\xff\xff\xff\xaf\xfd\x07\xdf[:\xbc\x95Q\x81 \xfb\xc7\xaa\xb5#q \x00I#\xcb\xc1\x11D\x11H\xfa\xdb\x94\x19hr\x10\xf4NY\x1b$\x8d\x0c\x90\x95~\xad\xacE\x97F\x03\x94H\xff\xff\x0f\x00\x1f]\xa2\x03U|Z\xa3\x00\x00\x00\x00IEND\xaeB`\x82'
edit: I feel like you might need more info on my situation: I am trying to make a little encryption program, and although it works on strings, I want to make it work for any file too. I am reading a .png file in byte-mode(which gives the string mentioned above), and after it is done being encrypted and decrypted, I have a string with the exact same content, but no way to put it back into a file.
For python3, you have to open the file in binary write mode and encode the string to bytes:
with open('filename', 'wb') as f:
f.write(the_string.encode())
You could try using PyPNG, looks like a possible solution:
http://pythonhosted.org/pypng/ex.html#writing
This will let you write binary to a file in python.
with open('filename', 'wb') as f:
f.write(bytecode)
I have a binary file (link) that I would like to open and read contents of with Python. How are such binary files opened and read with Python? Any specific modules to use for such an operation.
The 'b' flag will get python to treat the file as a binary, so no modules are needed. Also you haven't provided a purpose for having python read a binary file with a question like that.
f = open('binaryfile', 'rb')
print(f.read())
Here is an Example:
with open('somefile.bin', 'rb') as f: #the second parameter "rb" is used only when reading binary files. Term "rb" stands for "read binary".
data = f.read() #we are assigning a variable which will read whatever in the file and it will be stored in the variable called data.
print(data)
Reading a file in python is trivial (as mentioned above); however, it turns out that if you want to read a binary file and decode it correctly you need to know how it was encoded in the first place.
I found a helpful example that provided some insight at https://www.devdungeon.com/content/working-binary-data-python,
# Binary to Text
binary_data = b'I am text.'
text = binary_data.decode('utf-8') #Trans form back into human-readable ASCII
print(text)
binary_data = bytes([65, 66, 67]) # ASCII values for A, B, C
text = binary_data.decode('utf-8')
print(text)
but I was still unable to decode some files that my work created because they used an unknown encoding method.
Once you know how it is encoded you can read the file bit by bit and perform the decoding with a function of three.
I'm working on a little audio project and part of it requires using wave files and flac files. Im trying to figure out how to read the metadata in each and how to add tags manually. I'm having trouble figuring out how to read the bytes as they are.
I have been referencing this page and a couple others to see the full format of a Wave file however for some wave files I get some discrepancies. I want to be able to see the hexadecimal bytes in order to see what differences are occurring.
Using simply open('fname', 'rb') and read, only returns the bytes as strings. Using struct.unpack has worked for some wave files however it is limited to printing as strings, ints, or shorts and I can't see exactly what is going wrong when I use it. Is there any other way I can read this file in hex?
Thanks
I assume that you just want to display the content of a binary file in hexadecimal. First, you do not need to use Python for that, as some editors to it natively, for example vim.
Now assuming you have a string that you got by reading a file, you can easily change it to a list of hexadecimal values:
with open('fname', 'rb') as fd: # open the file
data = rd.read(16) # read 16 bytes from it
h = [ hex(ord(b)) for b in data] # convert the bytes to their hex value
print (h) # prints a list of hexadecimal codes of the read bytes