gpt4 book ai didi

python - 二进制流中 `open` 和 `io.BytesIO` 之间的区别

转载 作者:IT老高 更新时间:2023-10-28 21:33:17 32 4
gpt4 key购买 nike

我正在学习如何在 Python 中使用流,我注意到 IO docs说出以下内容:

The easiest way to create a binary stream is with open() with 'b' in the mode string:

f = open("myfile.jpg", "rb")

In-memory binary streams are also available as BytesIO objects:

f = io.BytesIO(b"some initial binary data: \x00\x01")

open定义的fBytesIO定义的f有什么区别。换句话说,是什么构成了“内存中的二进制流”,它与 open 的作用有何不同?

最佳答案

为简单起见,让我们现在考虑写作而不是阅读。

所以当你使用 open() 就像说:

with open("test.dat", "wb") as f:
f.write(b"Hello World")
f.write(b"Hello World")
f.write(b"Hello World")

执行后,将创建一个名为 test.dat 的文件,其中包含 3x Hello World。数据写入文件后不会保存在内存中(除非按名称保存)。

现在当你考虑 io.BytesIO() 时:

with io.BytesIO() as f:
f.write(b"Hello World")
f.write(b"Hello World")
f.write(b"Hello World")

不是将内容写入文件,而是写入内存缓冲区。换句话说,一大块 RAM。基本上写以下内容是等价的:

buffer = b""
buffer += b"Hello World"
buffer += b"Hello World"
buffer += b"Hello World"

与带有 with 语句的示例相关,那么最后也会有一个 del 缓冲区

这里的关键区别在于优化和性能。 io.BytesIO 能够进行一些优化,使其比简单地连接所有 b"Hello World" 更快。​​

只是为了证明它是一个小基准:

  • 连续:1.3529 秒
  • BytesIO:0.0090 秒

import io
import time

begin = time.time()
buffer = b""
for i in range(0, 50000):
buffer += b"Hello World"
end = time.time()
seconds = end - begin
print("Concat:", seconds)

begin = time.time()
buffer = io.BytesIO()
for i in range(0, 50000):
buffer.write(b"Hello World")
end = time.time()
seconds = end - begin
print("BytesIO:", seconds)

除了性能增益之外,使用 BytesIO 代替连接的优点是 BytesIO 可以用来代替文件对象。所以说你有一个函数需要一个文件对象来写入。然后你可以给它那个内存缓冲区而不是一个文件。

不同的是 open("myfile.jpg", "rb") 只是简单地加载并返回 myfile.jpg 的内容;而 BytesIO 又只是一个包含一些数据的缓冲区。

由于 BytesIO 只是一个缓冲区 - 如果您想稍后将内容写入文件 - 您必须这样做:

buffer = io.BytesIO()
# ...
with open("test.dat", "wb") as f:
f.write(buffer.getvalue())

另外,你没有提到版本;我正在使用 Python 3。与示例相关:我使用 with 语句而不是调用 f.close()

关于python - 二进制流中 `open` 和 `io.BytesIO` 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42800250/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com