Python StreamIO从同一流读取和写入

Python StreamIO从同一流读取和写入,python,inputstream,Python,Inputstream,我正在寻找一种pythonic方法,既可以读取流,也可以写入流(在IOBase层次结构中),而不必通过seek()和tell()管理流的位置。这将类似于套接字流的工作方式,其中接收端能够连续读取接收到的字节 我尝试过使用连接到同一原始流的BufferedReader和BufferedWriter,但其中一个上的操作会影响另一个上的流位置。seek()/tell()似乎直接传递到底层原始流。是否有其他IOBASE类型可以用来有效地充当IO流,在不需要管理流位置的情况下支持并发输入和输出(类似于C+

我正在寻找一种pythonic方法,既可以读取流,也可以写入流(在IOBase层次结构中),而不必通过seek()和tell()管理流的位置。这将类似于套接字流的工作方式,其中接收端能够连续读取接收到的字节

我尝试过使用连接到同一原始流的BufferedReader和BufferedWriter,但其中一个上的操作会影响另一个上的流位置。seek()/tell()似乎直接传递到底层原始流。是否有其他IOBASE类型可以用来有效地充当IO流,在不需要管理流位置的情况下支持并发输入和输出(类似于C++ StrueSnc>>和

,不能直接。

套接字与一对文件描述符无关,一个用于读取,一个用于写入。这就是为什么允许您在套接字上读取和写入,而无需在不同操作之间使用seek

如果您确实想用
StringIO
BytesIO
模拟套接字,只需构建一个包含一对或多对的自定义类

可能是这样的:

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()
如果您需要一个环回伪套接字(读取之前编写的内容),您可以使用:

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)

以下简单的字符串示例的运行速度比上面Serge的第二个示例快很多(至少在流中保存的数据相对较小的情况下),并且可以对同一流进行简单的读写操作:

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

我不确定这是否满足我的需要。写入输出(通过写入(…)的字节需要通过read()和readinto()返回。啊,好多了。唯一的缺点是每次读/写时都要复制缓冲区。@Stanton:我编辑了我的帖子,给出了如何使用可变序列的提示。在第二个例子中,
inputText
的默认参数必须是
b'
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