我试图了解 io.BytesIO 的 write()和 read()方法。 我的理解是,我可以像使用文件一样使用 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 有关,但是我不清楚。
答案 0 :(得分:4)
这是一个内存流,但仍然是一个流。位置已存储,因此,与其他任何流一样,如果您尝试在写入后阅读,则必须重新定位:
let arr = [{Code: "AT", Country: "Austria", Nationality: "Austrian"}
,{Code: "BE", Country: "Belgium", Nationality: "Belgian"}
,{Code: "CH", Country: "Switzerland", Nationality: "Swiss"}
,{Code: "DE", Country: "Germany", Nationality: "German"}
,{Code: "ES", Country: "Spain", Nationality: "Spanish"}
,{Code: "IT", Country: "Italy", Nationality: "Italian"}
,{Code: "NL", Country: "Netherlands", Nationality: "Dutch"}
,{Code: "PL", Country: "Poland", Nationality: "Polish"}]
arr.sort((a,b) => a.Country.localeCompare(b.Country))
console.log(arr)
打印:
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'
不需要最后的in_memory.getvalue()
,因为它从位置0返回流的内容。
答案 1 :(得分:4)
问题在于您位于流的末尾。将该位置想像为光标。写入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'hello'
已被您写入b' world'
覆盖。
.getvalue()
仅返回流的全部内容,而与当前位置无关。
答案 2 :(得分:2)
BytesIO
的行为就像一个文件,只有一个文件可以读取和写入。可能令人困惑的部分是读写位置是相同的。所以首先你要做:
in_memory = io.BytesIO(b'hello')
这将为您提供in_memory
中的字节缓冲区,其内容为b'hello'
,并且读/写位置位于开头(在第一个b'h'
之前)。当您这样做时:
in_memory.write(b' world')
您实际上用b'hello'
覆盖了b' world'
(实际上又增加了一个字节),现在位置在末尾(在最后一个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
,如其他答案所指出,它为您提供了完整的内部缓冲区,而与当前位置无关。该操作显然不适用于文件。