【发布时间】:2013-01-11 17:01:31
【问题描述】:
我想读取字节。 sys.stdin 以文本模式打开,但它有一个可用于读取字节的缓冲区:sys.stdin.buffer。
我的问题是,当我将数据通过管道传输到 python 时,如果我想要预读,我似乎只有 2 个选项,否则我会得到一个 io.UnsupportedOperation: File or stream is not seekable.
-
从
sys.stdin读取缓冲文本,将该文本解码为字节,然后返回(
sys.stdin.read(1).decode(); sys.stdin.seek(-1, io.SEEK_CUR).由于输入流中的字节不可编码而无法接受。
-
使用
peek从标准输入的缓冲区中获取一些字节,将其分割成适当的数字,然后祈祷,因为peek并不能保证任何事情:它可能提供的比您要求的要少或多……(
sys.stdin.buffer.peek(1)[:1])peek 的文档确实不足,并为您提供了一堆字节,您必须对这些字节进行性能密集型切片。
顺便说一句。该错误仅在管道时适用:对于./myscript.py <somefile,sys.stdin.buffer 支持查找。然而sys.stdin 始终是相同的对象层次结构:
$ cat testio.py
#!/usr/bin/env python3
from sys import stdin
print(stdin)
print(stdin.buffer)
print(stdin.buffer.raw)"
$ ./testio.py
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>
<_io.BufferedReader name='<stdin>'>
<_io.FileIO name='<stdin>' mode='rb'>
$ ./testio.py <somefile
[the same as above]
$ echo hi | ./testio.py
[the same as above]
一些最初的想法,例如将字节流包装到随机访问缓冲区中,并出现与上述相同的错误:BufferedRandom(sys.stdin.buffer).seek(0) ⇒ io.UnsupportedOperation…
最后,为了您的方便,我介绍一下:
Python 的 io 类层次结构
IOBase
├RawIOBase
│└FileIO
├BufferedIOBase (buffers a RawIOBase)
│├BufferedWriter┐
│├BufferedReader│
││ └─────┴BufferedRWPair
│├BufferedRandom (implements seeking)
│└BytesIO (wraps a bytes)
└TextIOBase
├TextIOWrapper (wraps a BufferedIOBase)
└TextIO (wraps a str)
如果您忘记了这个问题:如何在不解码/编码任何内容且不前进流的光标的情况下从标准输入获取下一个字节?
【问题讨论】:
-
我提交了python issue 16937,因为我被引导相信您可以使用
-u来禁用stdin上的缓冲。到目前为止,您还没有答案。 -
你知道让 peek 正常工作的标准输入缓冲区大小吗?
标签: python python-3.x