From documents, you can read binary data (as a bytes type) from stdin using sys.stdin.buffer.read() :
To write or read binary data from / to standard streams, use the underlying binary buffer object. For example, to write bytes to stdout, use sys.stdout.buffer.write (b'abc ').
So, this is one direction you can take - read the data in binary mode. readline() and other functions still work. Once you have captured an ASCII string, you can convert it to text using decode('ASCII') for extra text processing.
Alternatively, you can use io.TextIOWrapper() to indicate the use of the latin-1 character set in the input stream. In this case, the implicit decoding operation will essentially go through a pass-through operation, so the data will be of type str (which represent the text), but the data is represented by a 1-to-1 mapping from binary (although it can use more than one storage byte per input byte) .
Here is the code that works in any mode:
#! /usr/bin/python3 import sys, io BINARY=True ## either way works if BINARY: istream = sys.stdin.buffer else: istream = io.TextIOWrapper(sys.stdin.buffer,encoding='latin-1') header = istream.readline() if BINARY: header = header.decode('ASCII') print("header=["+header.strip()+"]") payload = istream.read() print("len="+str(len(payload))) for i in payload: print( i if BINARY else ord(i) )
Check every possible 1-pixel payload with the following Bash command:
for i in $(seq 0 255) ; do printf "P5 1 1 255\n\x$(printf %02x $i)" |./test.py ; done
nobar Jul 18 '15 at 23:51 2015-07-18 23:51
source share