我可以将io.BytesIO()流传输到Python中的subprocess.popen()吗? [英] Can I pipe a io.BytesIO() stream to subprocess.popen() in Python?

查看:144
本文介绍了我可以将io.BytesIO()流传输到Python中的subprocess.popen()吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 subprocess.popen() io.BytesIO() bytetream管道输送到单独的程序,但是我不知道怎么做或是否完全有可能.文档和示例都是关于文本和换行符的.

I'm trying to pipe a io.BytesIO() bytetream to a separate program using subprocess.popen(), but I don't know how or if this is at all possible. Documentation and examples are all about text and newlines.

当我鞭打这样的东西时:

When I whip up something like this:

import io
from subprocess import *

stream = io.BytesIO()
someStreamCreatingProcess(stream)

command = ['somecommand', 'some', 'arguments']  
process = Popen(command, stdin=PIPE)
process.communicate(input=stream)

我知道

Traceback (most recent call last):
  File "./test.py", line 9, in <module>
    procOut         = process.communicate(input=stream)
  File "/usr/lib/python2.7/subprocess.py", line 754, in communicate
    return self._communicate(input)
  File "/usr/lib/python2.7/subprocess.py", line 1322, in _communicate
    stdout, stderr = self._communicate_with_poll(input)
  File "/usr/lib/python2.7/subprocess.py", line 1384, in _communicate_with_poll
    chunk = input[input_offset : input_offset + _PIPE_BUF]
TypeError: '_io.BytesIO' object has no attribute '__getitem__'

我认为 popen()仅适用于文本.我错了吗?
有其他方法可以做到吗?

I think popen() is only for text. Am I wrong?
Is there a different way to do this?

推荐答案

正如 @falsetru所说的,您无法流式传输直接BytesIO()对象;您需要先从中获取一个字节串.这意味着在调用stream.getvalue()传递给process.communicate()之前,所有内容都应该已经写入stream .

As @falsetru said you can't stream BytesIO() object directly; you need to get a bytestring from it first. It implies that all content should be already written to stream before you call stream.getvalue() to pass to process.communicate().

如果要而不是一次提供所有输入,则可以删除BytesIO()对象并直接写入管道:

If you want to stream instead of providing all input at once then you could drop BytesIO() object and write to the pipe directly:

from subprocess import Popen, PIPE

process = Popen(['command', 'arg1'], stdin=PIPE, bufsize=-1)
someStreamCreatingProcess(stream=process.stdin) # many `stream.write()` inside
process.stdin.close() # done (no more input)
process.wait()

someStreamCreatingProcess()在完成写入流之前不应该返回.如果立即返回,则应在将来的某个时间调用stream.close()(在代码中删除process.stdin.close()):

someStreamCreatingProcess() should not return until it is done writing to the stream. If it returns immediately then it should call stream.close() at some point in the future (remove process.stdin.close() in your code):

from subprocess import Popen, PIPE

process = Popen(['command', 'arg1'], stdin=PIPE, bufsize=-1)
someStreamCreatingProcess(stream=process.stdin) # many `stream.write()` inside
process.wait() # stream.close() is called in `someStreamCreatingProcess`

这篇关于我可以将io.BytesIO()流传输到Python中的subprocess.popen()吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆