<p>为了简单起见,现在让我们考虑写作而不是阅读。</p>
<p>所以当你用<code>open()</code>比如说:</p>
<pre><code>with open("test.dat", "wb") as f:
f.write(b"Hello World")
f.write(b"Hello World")
f.write(b"Hello World")
</code></pre>
<p>执行后,将创建名为<code>test.dat</code>的文件,其中包含<code>Hello World</code>。数据写入文件后不会保存在内存中(除非用名称保存)。</p>
<p>现在当你考虑<code>io.BytesIO()</code>时:</p>
<pre><code>with io.BytesIO() as f:
f.write(b"Hello World")
f.write(b"Hello World")
f.write(b"Hello World")
</code></pre>
<p>它不是将内容写入文件,而是写入内存缓冲区。换句话说就是一块内存。基本上,写下以下内容是等效的:</p>
<pre><code>buffer = b""
buffer += b"Hello World"
buffer += b"Hello World"
buffer += b"Hello World"
</code></pre>
<p><em>对于带有with语句的示例,最后还会有一个<code>del buffer</code>。</em></p>
<p>这里的关键区别在于优化和性能。<code>io.BytesIO</code>能够进行一些优化,使其比简单地逐个连接所有<code>b"Hello World"</code>更快。</p>
<p>为了证明这是一个小基准:</p>
<ul>
<li>Concat:1.3529秒</li>
<li>字节:0.0090秒</li>
</ul>
<p/>
<pre><code>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)
</code></pre>
<p>除了性能提高之外,使用<code>BytesIO</code>而不是连接还具有<code>BytesIO</code>可以代替文件对象的优点。假设有一个函数需要一个文件对象写入。然后你可以给它一个内存缓冲区而不是一个文件。</p>
<p>区别在于<code>open("myfile.jpg", "rb")</code>只是加载并返回<code>myfile.jpg</code>的内容;而<code>BytesIO</code>又是一个包含一些数据的缓冲区。</p>
<p>由于<code>BytesIO</code>只是一个缓冲区-如果以后要将内容写入文件,则必须执行以下操作:</p>
<pre><code>buffer = io.BytesIO()
# ...
with open("test.dat", "wb") as f:
f.write(buffer.getvalue())
</code></pre>
<p><em>另外,您没有提到版本;我使用的是Python3。与示例相关:我使用with语句而不是调用<code>f.close()</code></em></p>