Betrachten wir der Einfachheit halber zunächst das Schreiben statt das Lesen.
Also, wenn Sie open()
wie sagen:
with open("test.dat", "wb") as f:
f.write(b"Hello World")
f.write(b"Hello World")
f.write(b"Hello World")
Nach dem Ausführen wird eine aufgerufene Datei test.dat
erstellt, die 3x enthält Hello World
. Die Daten werden nach dem Schreiben in die Datei nicht gespeichert (es sei denn, sie werden unter einem Namen gespeichert).
Nun, wenn Sie io.BytesIO()
stattdessen überlegen :
with io.BytesIO() as f:
f.write(b"Hello World")
f.write(b"Hello World")
f.write(b"Hello World")
Anstatt den Inhalt in eine Datei zu schreiben, wird er in einen In-Memory-Puffer geschrieben. Mit anderen Worten, ein Stück RAM. Im Wesentlichen wäre das Folgende das Äquivalent:
buffer = b""
buffer += b"Hello World"
buffer += b"Hello World"
buffer += b"Hello World"
In Bezug auf das Beispiel mit der with-Anweisung würde es am Ende auch eine geben del buffer
.
Der Hauptunterschied ist hier die Optimierung und Leistung. io.BytesIO
ist in der Lage, einige Optimierungen vorzunehmen, die es schneller machen, als einfach alle b"Hello World"
nacheinander zu verketten .
Nur um es zu beweisen, hier ein kleiner Maßstab:
- Concat: 1,3529 Sekunden
- BytesIO: 0,0090 Sekunden
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)
Neben dem Leistungsgewinn hat die Verwendung BytesIO
anstelle der Verkettung den Vorteil, dass sie anstelle eines Dateiobjekts BytesIO
verwendet werden kann. Angenommen, Sie haben eine Funktion, die erwartet, dass ein Dateiobjekt geschrieben wird. Dann können Sie ihm diesen speicherinternen Puffer anstelle einer Datei geben.
Der Unterschied besteht darin, dass open("myfile.jpg", "rb")
einfach der Inhalt von geladen und zurückgegeben wird myfile.jpg
. Auch hier BytesIO
handelt es sich nur um einen Puffer, der einige Daten enthält.
Da BytesIO
es sich nur um einen Puffer handelt - wenn Sie den Inhalt später in eine Datei schreiben möchten - müssen Sie Folgendes tun:
buffer = io.BytesIO()
with open("test.dat", "wb") as f:
f.write(buffer.getvalue())
Außerdem haben Sie keine Version erwähnt. Ich verwende Python 3. Bezogen auf die Beispiele: Ich verwende die with-Anweisung, anstatt sie aufzurufenf.close()
in memory stream
und Sie haben verwiesenin memory buffer
. Gibt es einen Unterschied in Python? Es lohnt sich, kurz darauf einzugehen. Aus englischer semantischer Sichtstream
impliziert dies einen kontinuierlichen Fluss von Bits von der Quelle zur Senke (Pushing von der Quelle), wobei der Puffer einen Cache von Bits in der Quelle impliziert, der zum schnellen Abrufen von Blöcken oder Stücken von der Quelle bereit ist (die Senke zieht von der Quelle ).