views:

30

answers:

1

I am trying to read binary data from sys.stdin using Python 2.7 on Windows XP. The binary data is a WAV file decoded by foobar2000. Normally, this data is sent to a command-line encoder such as lame.exe on stdin, where it is processed and written to an output file whose name is provided in the command-line arguments. I am trying to intercept the WAV data that is output and send it to another file. However, I can only get a few KB from stdin before the pipeline apparently collapses, and so I am left with only a very short (about 75 KB) WAV file, instead of the several tens of megabytes that I am expecting. What might be causing this? I have been careful to open both sys.stdin and the output file as binary files.

from __future__ import print_function
import os
import os.path
import sys

sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0) # Make sys.stdin binary

wave_fname = os.path.join(os.environ['USERPROFILE'], 'Desktop',
    'foobar_test.wav')

try:
    os.remove(wave_fname)
except Exception:
    pass

CHUNKSIZE = 8192
wave_f = open(wave_fname, 'wb')
try:
    bytes_read = sys.stdin.read(CHUNKSIZE)
    while bytes_read:
        for b in bytes_read:
            wave_f.write(b)
        bytes_read = sys.stdin.read(CHUNKSIZE)
finally:
    pass
wave_f.close()
A: 

Suggestion: maybe you need to use msvcrt.setmode(fd, flags) where fd is sys.stdin.fileno()

John Machin
That worked beautifully, but why doesn't os.fdopen(sys.stdin.fileno(), 'rb', 0) work?
ascent1729
@ascent1729: Probably because it is applying `'b'` (too late) to the bytes it gets from the underlying file, which is open in text mode. Using `msvcrt.setmode` changes that to binary mode.
John Machin