pyInTheSky
pyInTheSky

Reputation: 1469

Python pipe in binary file from command line -u option

Is there a decoupled method of passing in a binary file without suffering the penalty of python having unbuffered stdout for the entire duration of running a program (if i intend to use only cmdline and not open(...,'rb')? It seems like -u is the only way to read in a file as binary data (from cmdline)

http://docs.python.org/using/cmdline.html

-u Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode.

Upvotes: 0

Views: 1354

Answers (2)

wberry
wberry

Reputation: 19367

This code will change standard input (only) to unbuffered mode. Using this you will not need to invoke the interpreter with -u. Unix only.

import fcntl, os, sys

def set_fd_nonblocking(fd):
  u"put an open file descriptor into non-blocking I/O mode"
  if fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) != 0:
    raise IOError, "can't set file descriptor %s option O_NONBLOCK" % (fd,)

set_fd_nonblocking(sys.stdin.fileno())

However I am unsure what side effects this could have, for example on the raw_input built-in function.

Be careful; even in non-blocking mode, if select tells you the fd is ready to read you will still need to catch OSError and check for e.errno == os.errno.EAGAIN. Such errors should be ignored.

Upvotes: 0

Amber
Amber

Reputation: 527143

You could perhaps avoid Python's file mode by instead grabbing the fileno out of the sys.stdin file-like object, and using os.read() to grab data from it?

import os
import sys

stdin_no = sys.stdin.fileno()
some_bytes = os.read(stdin_no, 1024)

Upvotes: 1

Related Questions