Python io.BytesIO的write()、read()和getvalue()方法是如何工作的



我正在尝试理解io的write((read((方法。BytesIO。我的理解是我可以使用io。BytesIO,因为我会使用文件对象

import io
in_memory = io.BytesIO(b'hello')
print( in_memory.read() )

上面的代码将按预期返回b'hello',但下面的代码将返回一个空字符串b''

import io
in_memory = io.BytesIO(b'hello')
in_memory.write(b' world')
print( in_memory.read() )

我的问题是:

-io.BytesIO.write(b' world')究竟在做什么?

-io之间有什么区别。BytesIO.read((io。BytesIO.getvalue((

我认为答案与io有关。BytesIO是一个流对象,但我不清楚大局。

问题是您处于流的末尾。把这个位置想象成一个光标。一旦您编写了b' world',您的光标就位于流的末尾。当您尝试.read()时,您正在读取光标位置之后的所有内容——这没有什么,所以您得到了空的字节串。

要在流中导航,可以使用.seek方法:

>>> import io
>>> in_memory = io.BytesIO(b'hello', )
>>> in_memory.write(b' world')
>>> in_memory.seek(0)  # go to the start of the stream
>>> print(in_memory.read())
b' world'

请注意,就像write('w'(模式中的文件流一样,b' world'的写入已经覆盖了初始字节b'hello'

.getvalue()只是返回流的全部内容,而与当前位置无关。

这是一个内存流,但仍然是一个流。位置是存储的,所以就像任何其他流一样,如果你在写完后试图阅读,你必须重新定位:

import io
in_memory = io.BytesIO(b'hello')
in_memory.seek(0,2)   # seek to end, else we overwrite
in_memory.write(b' world')
in_memory.seek(0)    # seek to start
print( in_memory.read() )

打印:

b'hello world'

而CCD_ 10不需要最终的CCD_。

BytesIO的行为确实像一个文件,只是一个既能读又能写的文件。令人困惑的部分可能是,阅读和写作的位置是相同的。所以你首先要做的是:

in_memory = io.BytesIO(b'hello')

这在in_memory中为您提供了一个字节缓冲区,内容为b'hello',读/写位置在开头(在第一个b'h'之前(。当你这样做:

in_memory.write(b' world')

您实际上是在用b' world'覆盖b'hello'(实际上又多了一个字节(,现在您的位置在末尾(在最后一个b'd'之后(。所以当你这样做的时候:

print( in_memory.read() )

您什么也看不到,因为当前位置后没有可读取的。然而,你可以使用seek来移动位置,所以如果你进行

import io
in_memory = io.BytesIO(b'hello')
in_memory.write(b' world')
in_memory.seek(0)
print( in_memory.read() )

你得到:

b' world'

请注意,您看不到初始b'hello',因为它已被覆盖。如果你想在之后写的初始内容,你可以先搜索到最后:

import io
in_memory = io.BytesIO(b'hello')
in_memory.seek(0, 2)
in_memory.write(b' world')
in_memory.seek(0)
print( in_memory.read() )

输出:

b'hello world'

编辑:关于getvalue,正如其他答案所指出的,它为您提供了完整的内部缓冲区,与当前位置无关。此操作显然不适用于文件。

相关内容

  • 没有找到相关文章

最新更新