首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从同一流中读取和写入StreamIO

从同一流中读取和写入StreamIO
EN

Stack Overflow用户
提问于 2015-10-28 15:22:20
回答 3查看 6.8K关注 0票数 11

我正在寻找一种pythonic的方法,既可以读写流(在IOBase层次结构中),又不需要通过for ()和tell()管理流位置。这将类似于期望套接字流在接收端能够连续读取接收的字节时工作的方式。

我尝试使用一个BufferedReader和BufferedWriter,它们都附加到相同的原始流中,但是对其中一个的操作会影响另一个流的位置。seek()/tell()似乎直接传递到底层原始流。是否有其他IOBase类型可以有效地充当IO流,其中支持并发输入和输出而不需要管理流位置(类似于C++、字符串流、>>和<< )。

谢谢!

代码语言:javascript
复制
>>> import io
>>> buf = io.BytesIO()
>>> r = io.BufferedReader(buf)
>>> w = io.BufferedWriter(buf)
>>> w.write('foo bar')
7L
>>> r.read(1)
''
>>> r.tell()
0L
>>> w.flush()
>>> r.tell()
7L
>>> r.flush()
>>> r.tell()
7L
>>> w.tell()
7L
>>> buf.tell()
7L
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-10-28 16:19:56

你不能直接。

套接字对应于一对文件描述符,一个用于读取,另一个用于写入。这就是为什么允许您在套接字上读写而不需要在不同操作之间使用搜索的原因。

如果您真的想用StringIOBytesIO模拟套接字,只需构建一个包含一对或它们的自定义类。

可能是这样的:

代码语言:javascript
复制
class BytesSocket(io.IOBase):
    def __init__(self, inputText):
        self.input = io.BytesIO(inputText)
        self.output = io.BytesIO()
    def read(self, n=-1):
        return self.input.read(n)
    def readinto(self, b):
        return self.input.readinto(b)
    def write(self, b):
        return self.output.write(b)
    def getoutvalue(self):
        return self.output.getvalue()

如果您需要一个环回伪套接字(读取以前所写的内容),您可以使用:

代码语言:javascript
复制
class BytesLoop(io.IOBase):
    def __init__(self, inputText=''):
        self.buf = inputText
    def read(self, n=-1):
        inp = io.BytesIO(self.buf)
        b = inp.read(n)
        self.buf = self.buf[len(b):]
        return b
    def readinto(self, b):
        inp = io.BytesIO(buf)
        l = inp.readinto(b)
        self.buf = self.buf[l:]
        return l
    def write(self, b):
        outp = io.BytesIO()
        l = outp.write(b)
        self.buf += outp.getvalue()
        return l
    def getvalue(self):
        return self.buf

由于str (或unicode)是不可变的序列,它需要为每个io操作重新编写。您可以轻松地使用一个字符列表,这些字符是可变的。您可以使用l = [c for c in s ]将字符串转换为列表,而使用s = ''.join(l)则可以进行相反的转换。

票数 3
EN

Stack Overflow用户

发布于 2018-03-01 19:53:01

下面的简单字符串示例比Serge上面的第二个示例运行得更快(至少如果流中的数据相对较小),并且可以对同一流进行简单的读写操作:

代码语言:javascript
复制
class BytesLoop:
    def __init__(self, s=b''):
        self.buffer = s

    def read(self, n=-1):
        chunk = self.buffer[:n]
        self.buffer = self.buffer[n:]
        return chunk

    def write(self, s):
        self.buffer += s
票数 3
EN

Stack Overflow用户

发布于 2022-01-06 06:52:27

我认为以前的答案并不安全.虽然可以这样做,例如:

代码语言:javascript
复制
class BytesLoop:
    def __init__(self, s=b''):
        self.buffer = s
        self.lock = threading.Lock()

    def read(self, n=-1):
        with self.lock:
            chunk = self.buffer[:n]
            self.buffer = self.buffer[n:]
        return chunk

    def write(self, s):
        with self.lock:
            self.buffer += s
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33395004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档