Seite 1 von 1

Effektivste Art für Dateien r/w

Verfasst: Donnerstag 1. Juni 2017, 09:29
von may24x
Hallo zusammen,
ich baue gerade ein Script was die Header Informationen gewisser Dateien ändert.
D.h. ich lese erst mal binär 32 Bytes, analysiere bzw. verbiege sie und schreibe sie in ein neues File.

Nur jetzt müssen nur noch die restlichen 500MB (unverändert) hinterher ...
Und hier die Frage, wie mache ich das am effektivsten ... ohne mir die 500MB komplett in den Speicher zu knallen ...

Re: Effektivste Art für Dateien r/w

Verfasst: Donnerstag 1. Juni 2017, 10:02
von BlackJack
@may24x: Schau Dir mal das `shutil`-Modul aus der Standardbibliothek an.

Re: Effektivste Art für Dateien r/w

Verfasst: Donnerstag 1. Juni 2017, 13:17
von DeaD_EyE

Code: Alles auswählen

In [1]: import shutil

In [2]: fd_writer = open('test.bin', 'wb')

In [3]: fd_reader = open('./Downloads/virtio-win-drivers-20120712-1.iso', 'rb')

In [4]: fd_writer.write(b'FOO_TEST')
Out[4]: 8

In [5]: shutil.copyfileobj(fd_reader, fd_writer)

In [6]: fd_writer.close(), fd_reader.close()
Out[6]: (None, None)

In [7]: fd = open('test.bin', 'rb')

In [8]: fd.read(10)
Out[8]: b'FOO_TEST\x00\x00'
Ich denke mal, dass copyfileobj sehr effektiv ist. Erst schreibst du den Header in die Datei und danach macht copyfileobj den Rest. Wenn du den Header von der ersten Datei entfernen willst/musst, kannst du das mit fd_in.seek(headersize) machen. Die Kopieroperation müsste dann bei den beiden Objekten an der Stelle wo der gerade ist, einfach weiter machen.

Re: Effektivste Art für Dateien r/w

Verfasst: Donnerstag 1. Juni 2017, 13:53
von Sirius3
@DeaD_EyE: was ist der Sinn, ein Tuple aus zwei None-Werten zu bilden, das man dann nicht benutzt?

Re: Effektivste Art für Dateien r/w

Verfasst: Donnerstag 1. Juni 2017, 15:25
von may24x
Hm scheint als würde der "seek" nicht funktionieren ...

Code: Alles auswählen

### build new file
in_file = open(inputfile, 'br')
out_file = open(outputfile, 'bw')

### part 1
data = in_file.read(66)
out_file.write(data)

### part 2
out_file.write(mod_data)

### part 3
shutil.copyfileobj(in_file.seek(72), out_file)
in_file.close()
out_file.close()
Traceback (most recent call last):
File "Q:\Lego Star wars\test\hevc_FPS-changer.py", line 8
shutil.copyfileobj((in_file.seek(72)), out_file)
File "C:\Users\vm\AppData\Local\Programs\Python\Python36-
ne 79, in copyfileobj
buf = fsrc.read(length)
AttributeError: 'int' object has no attribute 'read'

Re: Effektivste Art für Dateien r/w

Verfasst: Donnerstag 1. Juni 2017, 15:28
von Sirius3
@may24x: seek liefert kein Dateiobjekt zurück, sondern den vorherige Wert des Dateipositionszeigers.

Re: Effektivste Art für Dateien r/w

Verfasst: Donnerstag 1. Juni 2017, 15:33
von may24x
exakt ... aber wie kann ich das Datenmodell um besagte 72 bytes "kürzen" ?
Denn sonst hab ich die Daten ja doppelt drinne stehen ... ?

oder langt etwa ein:

Code: Alles auswählen

in_file.seek(72)
shutil.copyfileobj(in_file, out_file)

Re: Effektivste Art für Dateien r/w

Verfasst: Donnerstag 1. Juni 2017, 15:39
von may24x
Ah, hat sich erledigt :)
Ja, es geht tatsächlich so: Erst den Pointer mit dem "seek" setzen und dann einfach kopieren ...

Code: Alles auswählen

### part 3
in_file.seek(72)
shutil.copyfileobj(in_file, out_file)
Vielen Dank für eure Hilfe

Re: Effektivste Art für Dateien r/w

Verfasst: Donnerstag 1. Juni 2017, 17:32
von BlackJack
@may24x: Ich persönlich hätte das `seek()` durch ein ``read(6)`` ausgedrückt, dann muss die Datei nicht „seekable“ sein.

Ein bisschen verwirrend finde ich die Namensgebung bei `in_file` und `inputfile` und `out_file` und `outputfile`, weil ja nur zwei davon wirklich Datei-Objekte sind und die anderen beiden Datei*namen*.