Bytefolge in Datei finden und verändern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Anbeku
User
Beiträge: 3
Registriert: Montag 11. Dezember 2017, 15:40

Hallo zusammen,

ich habe schon recht lange Erfahrung im Programmieren, allerdings nicht in Python. Für mein aktuelles Problem brauche ich allerdings eine "Skriptsprache" und da ist mir Python am liebsten. Hab damit schon einfache Sachen gemacht, aber bei meinem aktuellen Problem komme ich nicht vorwärts:

Ich möchte eine bestimmte Stelle in einer großen Binärdatei manipulieren. Dazu müsste ich erst mal die Stelle finden, die durch einen speziellen String gekennzeichnet ist und den "Dateicurser" dahinter bewegen. Daran scheitere ich. Gibt es eine fertige Lösung um eine Binärdatei zu durchsuchen oder muss ich das irgendwie "zu Fuss" programmieren? Hab da leider nichts gefunden.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das kommt drauf an. Wie gross ist denn deine Datei, und wie gross ist dein Hauptspeicher, wie gross die Needle, und wie gross das Stueck das ersetzt/eingefuegt wird?

Wenn die Datei zweimal in den Memory rein passt, dann ist es ein simples string-replace. Wenn nicht, dann werden es vielleicht 20 Zeilen mit blockweisem lesen, und sicherstellen, das man auch an Blockgrenzen die Suchstelle nicht verliert.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Solange die Datei in den virtuellen Adressraum passt, macht man so etwas mit MemoryMappedFiles, das sind dann drei Zeilen Code.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Sirius3 ich bin da nicht besonders bewandert, aber können mapped Dateien mit Verschiebungen gut um?
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: die meisten Binärdateien können nicht mit Verschiebungen umgehen. Daher gehe ich davon aus, dass Anbeku die Länge nicht ändern will. Ansonsten muß man halt erst alles bis zur Fundstelle in eine neue Datei schreiben, dann den Ersetzungstext, und dann alles danach.

Code: Alles auswählen

import mmap

with open(FILENAME, 'rb') as data:
    data = mmap.mmap(data.fileno(),0, access=mmap.ACCESS_READ)

index = data.find(SUCHTEXT)

with open(OUTPUTNAME, 'wb') as output:
    offset = 0
	while offset < index:
	    blocksize = min(4096, index-offset)
	    output.write(data[offset: blocksize])
		offset += blocksize
	output.write(ERSETZUNGSTEXT)
	offset += len(SUCHTEXT)
	index = len(data)
	while offset < index:
	    blocksize = min(4096, index-offset)
	    output.write(data[offset: blocksize])
		offset += blocksize
Will man die Datei inplace ändern, geht das dann viel kürzer:

Code: Alles auswählen

import mmap

with open(FILENAME, 'rwb') as data:
    data = mmap.mmap(data.fileno(), 0, access=mmap.ACCESS_READ)

index = data.find(SUCHTEXT)
data[index:index+len(ERSETZUNGSTEXT)] = ERSETZUNGSTEXT
data.close()
Anbeku
User
Beiträge: 3
Registriert: Montag 11. Dezember 2017, 15:40

Die Datei passt problemlos in den Speicher. Damit ist die Lösung eigentlich recht einfach. Hab mir da wohl zu viele Gedanken gemacht. danke euch allen.
Antworten