最近,我不得不用python的stdin和stdout进行I/O读取,并具有跨平台兼容性。
对于linux:
对于linux,我们可以使用select模块。它是posixselect函数的包装器实现。它允许您传递多个文件描述符,等待它们准备就绪。一旦他们准备好了,您将收到通知,并且可以执行read/write操作。下面是一些小代码,可以让您有一个想法
这里的nodejs是一个带有nodejs映像的docker环境stdin_buf = BytesIO(json.dumps(fn) + "\n")
stdout_buf = BytesIO()
stderr_buf = BytesIO()
rselect = [nodejs.stdout, nodejs.stderr] # type: List[BytesIO]
wselect = [nodejs.stdin] # type: List[BytesIO]
while (len(wselect) + len(rselect)) > 0:
rready, wready, _ = select.select(rselect, wselect, [])
try:
if nodejs.stdin in wready:
b = stdin_buf.read(select.PIPE_BUF)
if b:
os.write(nodejs.stdin.fileno(), b)
else:
wselect = []
for pipes in ((nodejs.stdout, stdout_buf), (nodejs.stderr, stderr_buf)):
if pipes[0] in rready:
b = os.read(pipes[0].fileno(), select.PIPE_BUF)
if b:
pipes[1].write(b)
else:
rselect.remove(pipes[0])
if stdout_buf.getvalue().endswith("\n"):
rselect = []
except OSError as e:
break
对于windows
这个代码示例包含stdin和stdout的读和写操作。
现在这段代码在windows操作系统上不起作用,因为在windows上,select IMPLELETION不允许stdin、stdout作为参数传递。
医生说:File objects on Windows are not acceptable, but sockets are. On Windows, the underlying select() function is provided by the WinSock library, and does not handle file descriptors that don’t originate from WinSock.
首先我必须指出,有很多库可以在windows上进行非阻塞I/O读取,比如asyncio(python3)、gevent(对于python2.7)、msvcrt,然后还有{}的win32event,它们会在套接字准备好read/write数据时提醒您。但是他们都不允许我读写关于stdin/stdout的错误,比如
An operation is performend on something that is not a socket
Handles only expect integer values等
还有一些其他库,比如twister,我还没有尝试过。在
现在,为了在windows平台上实现上述代码中的功能,我使用了threads。这是我的代码:
^{pr2}$
所以对我来说最好的选择就是线程。如果您想了解更多,本文将是nice read。在