2010-12-13 4 views
0

Ich versuche, Daten aus einer Datei im Binärmodus zu lesen und diese Daten zu manipulieren.Lesen und Schreiben von Binärdaten mit dynamischen Größen Frage

try: 
    resultfile = open("binfile", "rb") 
except: 
    print "Error" 
resultsize = os.path.getsize("binfile") 

Es gibt eine 32-Byte-Kopfzeile, die ich gut parse dann beginnt der Puffer von Binärdaten. Die Daten können eine beliebige Größe von 16 bis 4092 haben und können in einem beliebigen Format vorliegen, von Text bis zu einem PDF oder Bild oder irgendetwas anderem. Der Header hat die Größe der Daten, so dass ich diese Informationen

contents = resultfile.read(resultsize) 

und diese setzt die gesamte Datei in einen String-Puffer. Ich habe herausgefunden, dass dies wahrscheinlich mein Problem ist, denn wenn ich versuche, Teile der Hexadezimaldaten von "Inhalt" in eine neue Datei zu kopieren, werden einige Bytes nicht richtig kopiert, so dass pdfs und Bilder beschädigt werden.

Das Ausdrucken eines Teils des Datei-String-Puffers im Interpreter ergibt beispielsweise etwas wie "% PDF-1.5 \ r \ n% \ xb5 \ xb5 \ xb5 \ xb5 \ r \ n1 0 obj \ r \ n" wenn ich nur die Bytes selbst haben möchte, um sie in eine neue Datei zu schreiben. Gibt es eine einfache Lösung für dieses Problem, das ich vermisse? Hier

ist ein Beispiel für einen Hex-Dump mit dem pdf geschrieben mit meiner Python und der realen pdf:

25 50 44 46 2D 31 2E 35 0D 0D 0A 25 B5 B5 B5 B5 0D 0D 0A 31 20 30 20 6F 62 6A 0D 0D 0A 

25 50 44 46 2D 31 2E 35 0D 0A 25 B5 B5 B5 B5 0D 0A 31 20 30 20 6F 62 6A 

Es scheint wie ein 0D hinzugefügt wird, wenn es ein 0D 0A ist. In Bilddateien könnte es ein anderes Byte sein, an das ich mich nicht erinnern kann und das ich vielleicht testen müsste. Mein Code, um die neue Datei zu schreiben, ist ziemlich einfach, mit Inhalt als String-Puffer, der alle Daten enthält.

 fbuf = contents[offset+8:size+offset] 
     fl = open(fname, 'a') 
     fl.write(fbuf) 

Dies wird in einer Schleife basierend auf einer Signatur aufgerufen, die in der Kopfzeile gefunden wird. Offset + 8 ist der Beginn der tatsächlichen PDF-Daten und die Größe ist die Größe des zu kopierenden Chunks.

+2

Sie können auch anrufen '' resultfile.read(), um die gesamte Datei zu lesen. –

+0

'resultfile.read()' wird den gesamten Inhalt der Datei als String zurückgeben. Gibt es einen Grund, warum du zuerst die Größe ergreifst? – nmichaels

+0

Kein Grund, ich wusste einfach nicht lese() wird die gesamte Datei zurückgeben. –

Antwort

2

Sie müssen Ihre Ausgabedatei im Binärmodus öffnen, wie Sie Ihre Eingabedatei tun. Andernfalls können Newline-Zeichen geändert werden. Sie können sehen, dass dies in Ihrem Hexadezimalspeicher geschieht: 0A Zeichen ('\n') werden in OD 0A ('\r\n') geändert.

sollte diese Arbeit:

input_file = open('f1', 'rb') 
contents = input_file.read() 

#.... 
data = contents[offset+8:size+offset] #for example 

output_file = open('f2', 'wb') 
output_file.write(data) 
+0

Danke, ich habe den Modus auf "ab" geändert und es funktioniert gut. Vielen Dank an alle. –

+0

@Tagspause: Wenn Sie diese Antwort hilfreich finden, sollten Sie sie als richtige Antwort akzeptieren, indem Sie auf das grüne Häkchen neben der Antwort klicken. –

0

Das Ergebnis ist "nur die Bytes selbst". Sie können sie in eine offene Datei schreiben(), um sie zu kopieren.

„Es scheint wie ein 0D hinzugefügt wird, sobald ein 0D 0A“

Klingt wie Sie auf Fenster, und Sie sind eine der Dateien im Textmodus statt binärer öffnen.