64

In Python 2.x with 'file-like' object:

sys.stdout.write(bytes_)
tempfile.TemporaryFile().write(bytes_)
open('filename', 'wb').write(bytes_)
StringIO().write(bytes_)

How to do the same in Python 3?

How to write equivalent of this Python 2.x code:

def write(file_, bytes_):
    file_.write(bytes_)

Note: sys.stdout is not always semantically a text stream. It might be beneficial to consider it as a stream of bytes sometimes. For example, make encrypted archive of dir/ on remote machine:

tar -c dir/ | gzip | gpg -c | ssh user@remote 'dd of=dir.tar.gz.gpg'

There is no point to use Unicode in this case.

jfs
  • 399,953
  • 195
  • 994
  • 1,670

2 Answers2

74

It's a matter of using APIs that operate on bytes, rather than strings.

sys.stdout.buffer.write(bytes_)

As the docs explain, you can also detach the streams, so they're binary by default.

This accesses the underlying byte buffer.

tempfile.TemporaryFile().write(bytes_)

This is already a byte API.

open('filename', 'wb').write(bytes_)

As you would expect from the 'b', this is a byte API.

from io import BytesIO
BytesIO().write(bytes_)

BytesIO is the byte equivalent to StringIO.

EDIT: write will Just Work on any binary file-like object. So the general solution is just to find the right API.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • Is there a way to write general function without resorting to type checking such as `isinstance(file_, io.TextIOWrapper)`, etc. – jfs Nov 27 '10 at 08:41
  • @J.F., Python 3 is designed specifically to handle the text v. binary divide properly. Without knowing the encoding, there is no correct way to go between binary and text. So there's no way to write a general function that writes bytes to a text stream. Dive Into Python 3 has a good [article](http://diveintopython3.org/strings.html) on this. – Matthew Flaschen Nov 27 '10 at 08:47
  • The question is specifically about *bytes*. For example, `os.write(sys.stdout.fileno(), bytes_)`. – jfs Nov 27 '10 at 08:59
  • So the answer is: pass an object whose '.write()' method accepts bytes; there are no shortcuts. – jfs Nov 27 '10 at 09:16
  • @MatthewFlaschen : Showing error `NameError: name 'bytes_' is not defined`, When `open('filename', 'wb').write(bytes_)` – timekeeper Jan 08 '16 at 09:06
  • @AayushKumarSingha: `bytes_` is your data e.g., `bytes_ = b'\x89PNG\r\n\x1a\n'` – jfs Jul 04 '17 at 15:44
31

Specify binary mode, 'b', when you open your file:

with open('myfile.txt', 'wb') as w:
    w.write(bytes)

https://docs.python.org/3.3/library/functions.html#open

bigonazzi
  • 714
  • 7
  • 6