Python - 2.5 - Writing binary to stdout

By default, Python sys.stdout is opened in text mode. So, if you want to write binary data to it, sys.stdout may product unexpected results between Windows and Linux

A classic example, 0x0A (or decimal 10) is representation for LF (newline) for ASCII. If you write 0x0A in binary to sys.stdout, a binary to text conversion will occur. Under Windows, it will generate as \r\n, while in Linux, it will generate as \n

If you want to try it out, write the following code to a binary_test.py

from struct import *
import sys
sys.stdout.write(pack('>I', 10))

Then, save it and run in command line

python binary_test.py > binary_test.dat

If you view it with OD, you will see the binary to text conversation under different platform

od -c binary_test.dat

In Windows



In Linux



Note: Windows is generating \r\n while Linux is generating \n with the same set of code.

In Python 3.X, there is a simple way to write binary to stdout. That is

sys.stdout.buffer.write(bytes)

In Python 2.X, you need to do the following

from struct import *
import sys
if sys.platform == 'win32':
  import os, msvcrt
  msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
sys.stdout.write(pack('>I', 10))

The above set of code can be compiled in Linux and run in Windows. The logic is simply changing text mode to binary mode only when the program detects Windows system.

Now, od -c binary_test.dat generate the following

In Windows



In Linux



As you can see, both has similar binary outcome

A side note, I had tested the following and won't work

sys.stdout = os.fdopen(1, "wb")

Where standard input is usually file descriptor 0, standard output is 1, and standard error is 2. Further files opened by a process will then be assigned 3, 4, 5, and so forth

References: http://code.activestate.com/recipes/65443-sending-binary-data-to-stdout-under-windows/

Comments

Popular Posts