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.daterstellt, 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.BytesIOist 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 BytesIOanstelle der Verkettung den Vorteil, dass sie anstelle eines Dateiobjekts BytesIOverwendet 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 BytesIOhandelt es sich nur um einen Puffer, der einige Daten enthält.
Da BytesIOes 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 streamund Sie haben verwiesenin memory buffer. Gibt es einen Unterschied in Python? Es lohnt sich, kurz darauf einzugehen. Aus englischer semantischer Sichtstreamimpliziert 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 ).