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 ).import io f = open("myfile.jpg", "rb") <class '_io.BufferedReader'> >>> isinstance(f, io.BufferedIOBase) True
Mit
open
öffnet eine Datei auf Ihrer Festplatte. Je nachdem, welchen Modus Sie verwenden, können Sie von der Festplatte lesen oder schreiben (oder beides).Ein
BytesIO
Objekt ist keiner realen Datei auf der Festplatte zugeordnet. Es ist nur ein Teil des Speichers, der sich wie eine Datei verhält. Es hat dieselbe API wie ein zurückgegebenes Dateiobjektopen
(mit Modusr+b
, der das Lesen und Schreiben von Binärdaten ermöglicht).BytesIO
(und es ist ein enges Geschwister,StringIO
das sich immer im Textmodus befindet) kann nützlich sein, wenn Sie Daten an oder von einer API übergeben müssen, die voraussichtlich ein Dateiobjekt erhalten, die Daten jedoch lieber direkt übergeben möchten. Sie können Ihre Eingabedaten in die laden,BytesIO
bevor Sie sie der Bibliothek übergeben. Nach der Rückkehr können SieBytesIO
mithilfe dergetvalue()
Methode alle Daten abrufen, die die Bibliothek in die Datei geschrieben hat . (Normalerweise müssten Sie natürlich nur eine davon machen.)quelle
f = open("myfile.jpg", "rb")
Lesen Sie Bytes aus der Datei von der Festplatte und weisen Sie diesen Wert dem Objekt zu, das als 'f' bezeichnet wird und von Python im Speicher gehalten wird.
f = io.BytesIO(b"some initial binary data: \x00\x01")
Weisen Sie dem Objekt, auf das als 'f' verwiesen wird und das von Python im Speicher gehalten wird, einen Byte-Stream-Wert zu.
quelle