Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python2.x-将二进制输出写入标准输出?_Python_Binary_Stdout - Fatal编程技术网

Python2.x-将二进制输出写入标准输出?

Python2.x-将二进制输出写入标准输出?,python,binary,stdout,Python,Binary,Stdout,在Python2.x中有没有办法将二进制输出写入sys.stdout?在Python3.x中,您可以只使用sys.stdout.buffer(或分离stdout等),但我还没有找到Python2.5/2.6的任何解决方案 编辑,解决方案: 来自ChristopheD的链接,如下: import sys if sys.platform == "win32": import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BI

在Python2.x中有没有办法将二进制输出写入sys.stdout?在Python3.x中,您可以只使用sys.stdout.buffer(或分离stdout等),但我还没有找到Python2.5/2.6的任何解决方案

编辑,解决方案: 来自ChristopheD的链接,如下:

import sys

if sys.platform == "win32":
    import os, msvcrt
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
编辑:我正在尝试将PDF文件(二进制格式)推送到标准输出,以便在web服务器上提供服务。当我尝试使用sys.stdout.write编写文件时,它会向二进制流中添加各种回车,从而导致PDF呈现损坏

编辑2:对于这个项目,我需要在Windows服务器上运行,不幸的是,Linux解决方案已经过时了

简单的虚拟示例(从磁盘上的文件读取,而不是动态生成,以便我们知道生成代码不是问题):


在Python2.x中,默认情况下所有字符串都是二进制字符数组,因此我相信您应该能够

>>> sys.stdout.write(data)
编辑:我已经证实了你的经验

我创建了一个文件gen_bytes.py

import sys
for char in range(256):
    sys.stdout.write(chr(char))
和另一个read_bytes.py

import subprocess
import sys

proc = subprocess.Popen([sys.executable, 'gen_bytes.py'], stdout=subprocess.PIPE)
res = proc.wait()
bytes = proc.stdout.read()
if not len(bytes) == 256:
    print 'Received incorrect number of bytes: {0}'.format(len(bytes))
    raise SystemExit(1)
if not map(ord, bytes) == range(256):
    print 'Received incorrect bytes: {0}'.format(map(ord, bytes))
    raise SystemExit(2)
print "Everything checks out"
将它们放在同一目录中并运行read_bytes.py。果不其然,看起来Python实际上是在转换输出上的换行符。我怀疑这只发生在Windows操作系统上

> .\read_bytes.py
Received incorrect number of bytes: 257
遵循ChristopheD的领导,并将gen_字节更改为以下内容,可以纠正此问题

import sys

if sys.platform == "win32":
    import os, msvcrt
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

for char in range(256):
    sys.stdout.write(chr(char))

为了完整性,我将其包括在内。克里斯托弗值得表扬。

你在哪个平台上

如果你在Windows上,你可以试试(链接显示它是Windows特有的)

在网上有一些参考资料表明,Python3.1中会/应该有一个函数以二进制模式重新打开
sys.stdout
,但我真的不知道是否有比上述Python2.x更好的替代方法。

您可以使用.argopen(),它将破折号作为stdin/stdout处理,并在Windows上修复二进制模式

import argopen
stdout = argopen.argopen('-', 'wb')
stdout.write(some_binary_data)

您可以使用无缓冲模式:
python-uscript.py

-u Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode. -u强制标准输入、标准输出和标准输出完全无缓冲。 在重要的系统上,还可以放置stdin、stdout和stderr 在二进制模式下。
我使用文件描述符的包装器解决了这个问题。(在Cygwin上用Python 3.2.5进行测试)


当您执行时,
sys.stdout.write()
什么不起作用?请参见上面的解释,但问题基本上是python在尝试将二进制流转换为字符串以进行写入时添加了回车符。
sys.stdout=os.fdopen(1,“wb”)
是否有助于您消除文本模式转换?(如果您不想从打印语句中获得NLs,您仍然需要使用sys.stdout.write。)()谢谢您提出的好问题。我今天学到了一些新东西。@Roger,令人惊讶的是,
os.fdopen
并没有解决这个问题,尽管用
-u
运行python是可行的
-u
确实会带来额外的开销,但如果您只是尝试添加字符串数据,那么这是可行的,但是python在调用write时会尝试将二进制数据字符串化,从而破坏数据。我在Mac OS X上运行了您的
gen_bytes.py
read_bytes.py
(Python2.5,对缺少的“format”关键字进行了少量修改),并且“一切正常“这似乎是Windows独有的问题。在Windows上,我发现只要运行
gen_bytes.py>bytes.bin
我就可以通过执行
dir
看到文件是257字节,除非您使用的是powershell,在这种情况下,
gen_bytes.py>bytes.bin
会生成一个522字节的unicode编码文件。我做了一个测试,只是从文件中读入PDF并直接写出来,回车符仍然会添加。您提供的windows解决方案链接是完美的解决方案。我对你感激不尽;这简直把我逼疯了。太棒了!同样的方法也适用于这两种情况,例如,制作一个能够处理二进制文件的功能性
cat
克隆需要这两种方法。这比ActiveState方法简单得多。你怎么知道的?该模块几乎没有文档记录。对我来说不起作用——我的发行版没有argopen。我不想安装它,因为上面提到的“msvcrt.setmode()”对我有效。此答案中的代码无法解决Python 2.7中的问题:
\r
字节仍然显示在Windows上的标准输出上。通过添加
msvcrt.setmode(self.fd,os.O_BINARY)
(如其他答案所示),
\r
字节消失。
import argopen
stdout = argopen.argopen('-', 'wb')
stdout.write(some_binary_data)
-u Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode.
class BinaryFile(object):
    ''' Wraps a file-descriptor to binary read/write. The wrapped
    file can not be closed by an instance of this class, it must
    happen through the original file.

    :param fd: A file-descriptor (integer) or file-object that
        supports the ``fileno()`` method. '''

    def __init__(self, fd):
        super(BinaryFile, self).__init__()
        fp = None
        if not isinstance(fd, int):
            fp = fd
            fd = fp.fileno()
        self.fd = fd
        self.fp = fp

    def fileno(self):
        return self.fd

    def tell(self):
        if self.fp and hasattr(self.fp, 'tell'):
            return self.fp.tell()
        else:
            raise io.UnsupportedOperation(
                'can not tell position from file-descriptor')

    def seek(self, pos, how=os.SEEK_SET):
        try:
            return os.lseek(self.fd, pos, how)
        except OSError as exc:
            raise io.UnsupportedOperation('file-descriptor is not seekable')

    def write(self, data):
        if not isinstance(data, bytes):
            raise TypeError('must be bytes, got %s' % type(data).__name__)
        return os.write(self.fd, data)

    def read(self, length=None):
        if length is not None:
            return os.read(self.fd, length)
        else:
            result = b''
            while True:
                data = self.read(1024)
                if not data:
                    break
                result += data
            return result