Python 2.x - Write binary output to stdout?
Which platform are you on?
You could try this recipe if you're on Windows (the link suggests it's Windows specific anyway).
if sys.platform == "win32":
import os, msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
There are some references on the web that there would/should be a function in Python 3.1 to reopen sys.stdout
in binary mode but I don't really know if there's a better alternative then the above for Python 2.x.
How to write binary data to stdout in python 3?
A better way:
import sys
sys.stdout.buffer.write(b"some binary data")
Writing bytes to standard output in a way compatible with both, python2 and python3
No need to test, just use getattr()
:
# retrieve stdout as a binary file object
output = getattr(sys.stdout, 'buffer', sys.stdout)
This retrieves the .buffer
attribute on sys.stdout
, but if it doesn't exist (Python 2) it'll return the sys.stdout
object itself instead.
Python 2:
>>> import sys
>>> getattr(sys.stdout, 'buffer', sys.stdout)
<open file '<stdout>', mode 'w' at 0x100254150>
Python 3:
>>> import sys
>>> getattr(sys.stdout, 'buffer', sys.stdout)
<_io.BufferedWriter name='<stdout>'>
Take into account that in Python 2, stdout
is still opened in text mode, newlines are still translated to os.linesep
when writing. The Python 3 BufferedWriter
object won't do this for you.
how to write bytes to stdout in python3.3
You can use os.fdopen
to reopen stdout with different mode. You can get the file number for stdout with sys.stdout.fileno()
.
Example:
>>> fp = os.fdopen(sys.stdout.fileno(), 'wb')
>>> fp.write(b'Hello, world')
12
>>> sys.stdout.mode
'w'
>>> fp.mode
'wb'
>>> fp.flush()
Hello, world>>>
What is the simplest way to write to stdout in binary mode?
You can use setmode(fileno(stdout), O_BINARY)
Wrap it in an ifdef if you want to keep it compatible with Linux.
See also: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?view=vs-2017
Why is the output different with Python 2.7 than Python 3.10?
I can't run this under Python 3.10.1 (Windows, 64-bit):
**Traceback (most recent call last):
File ... simple.py", line 39, in <module>
sys.stdout.write(chr(byte_acc))
File ... \lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\x80' in position 0: character maps to <undefined>
If I change the 2 instances of chr()
to str()
(so that it prints out a string representation of the byte's decimal value instead), it produces the same output under 3.10.1 and 2.7.11.
So you're getting burned by whatever default Unicode encoding scheme is used by your Python for sys.stdout
under Python 3.
If I set an envar like so (syntax may differ under your OS):
set PYTHONIOENCODING=latin-1
then both Pythons produce the same output using chr()
.
One way
Here's one way to "fix it":
import sys
from sys import stdout
if hasattr(stdout, "buffer"): # Python >= 3
def putbyte(b):
assert 0 <= b < 256
stdout.buffer.write(bytes([b]))
else: # before Python 3
def putbyte(b):
assert 0 <= b < 256
stdout.write(chr(b))
and then change your code to use putbyte(byte_acc)
instead of the current sys.stdout.write(chr(byte_acc))
.
That's not quite enough, though. Writing to the internal buffer yourself also makes you responsible for buffer management across uses. After the current
sys.stdout.write("P4\n%d %d\n" % (w, h))
you also need to add
sys.stdout.flush()
to get the output string into the buffer before you add additional output bytes.
How can I export binary data from Python subprocess command through STDOUT?
Turns out, this has nothing to do with Python. It's a Ghostscript error. As pointed out in this post: Prevent Ghostscript from writing errors to standard output, Ghostscript writes errors to stdout, which corrupts files that are piped out.
Thanks to @Jean-François Fabre who suggested I look in the binary files.
Related Topics
How to Force a List to a Fixed Size
Difference Between Type(Obj) and Obj._Class_
Python/Beautifulsoup - How to Remove All Tags from an Element
Failed to Upload Packages to Pypi: 410 Gone
How to Check If a Column Exists in Pandas
How to Generate a List of Consecutive Numbers
Save Results to CSV File with Python
How to Create Downloading Progress Bar in Ttk
Is There Any Built-In Way to Get the Length of an Iterable in Python
How to Find First Non-Zero Value in Every Column of a Numpy Array
How to Compare Dates in Django Templates
Print Current Call Stack from a Method in Code
What Does "Typeerror 'Xxx' Object Is Not Callable" Means
Unbuffered Stdout in Python (As in Python -U) from Within the Program
How to Do Virtual File Processing
How Come a File Doesn't Get Written Until I Stop the Program