File mit Binärteil einlesen

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
BastiL
User
Beiträge: 135
Registriert: Montag 7. Juli 2008, 20:22

Hallo zusammen,

ich möchte ein File einlesen, in dem teils Informationen binär gesichert sind. Das File lässt sich strukturiert in Blöcke aufteilen, die durch runde Klammern eingeschlossen sind,

( Dies ist ( ein ) Block) - So sieht ein Block aus.

Das File möchte ich jetzt beim Einlesen gleich in Blöcke aufteilen und habe einen Zähler eingeführt, der die "Klammertiefe" zählt. Wenn der Zähler auf null zurückfällt weiss ich, dass der Block zu Ende ist und ein neuer Block beginnt. Solange innerhalb des Blocks ASCII-Zeichen stehen klappt alles wunderbar, aber bei Blöcken die Binärdaten enthalten kommt die Prüfung (if __c == "(" bzw if __c == ")") durcheinander, weil sie die Binärdaten als ASCII interpretiert und teils "(" oder ")" sieht. Wie könnte ich so etwas lösen?

Danke BastiL
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Falls Du die Datei selbst erzeugst, könntest Du jeden Binärteil durch einen Marker zusammen mit einer Längeninformation über die folgenden Binärdaten einleiten. Ansonsten hast Du stets das Problem, das in den als Text interpretierten Binärdaten Zeichen vorkommen können, die das Parsing stören.

Klaus
BastiL
User
Beiträge: 135
Registriert: Montag 7. Juli 2008, 20:22

Ich erzeuge die Datei nicht selbst....

Allerdings kann man anhand der ersten Zeichen eines Blockes Rückschlüsse darauf ziehen, ob der Block Binär-Zeichen enthält oder nicht.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Wenn das Format, wie in deinem ersten Post beschrieben, so aufgebaut ist und keine weiteren Spezifikationen gegeben sind, ist das Einlesen im Allgemeinen nicht eindeutig. Entweder sind also noch Zusatzinformationen gegeben, oder das Format ist totaler Müll ;-)
Das Leben ist wie ein Tennisball.
BastiL
User
Beiträge: 135
Registriert: Montag 7. Juli 2008, 20:22

Es sind noch Zusatzinformationen gegeben, aber das Format ist trotzdem totaler Müll..... :wink:

Die Blöcke die Binär sein können haben folgende Form:

(Ordnungszahl (ASCII_HEADER) (Binärkrams))

Jetzt kann ich die Ordnungszahl auslesen und anhand der kann ich feststellen, ob da etwas binäres kommt oder nicht. So weit bin ich inzwischen. Der Header (ASCII) lässt obendrein noch Rückschlüsse darauf zu, wieviele Informationen genau in dem Binärteil stehen. Damit sollten wir doch ein Stück weiter kommen, oder?

BastiL
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BastiL hat geschrieben:Der Header (ASCII) lässt obendrein noch Rückschlüsse darauf zu, wieviele Informationen genau in dem Binärteil stehen.
Das solltest du nun genauer erklären. Ist es sowas wie Content-Length?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BastiL
User
Beiträge: 135
Registriert: Montag 7. Juli 2008, 20:22

Leonidas hat geschrieben:
BastiL hat geschrieben:Der Header (ASCII) lässt obendrein noch Rückschlüsse darauf zu, wieviele Informationen genau in dem Binärteil stehen.
Das solltest du nun genauer erklären. Ist es sowas wie Content-Length?
Nun quasi. Wenn ich den Header einlese kann ich indirekt darauf rückschließen (muss ich mir im Detail noch anschauen) wieviele Werte dort abgelegt sind. Aufgrund der Präzision der Maschine sollte ich auch die Byte-Länge der Fliesskomma-Zahlen rausbekommen können. Damit sollte mir doch geholfen sein, oder?

Jetzt ist es wohl so, dass auf Grund der Eigenheiten dieses Formats die Interpretation der Binärwerte bereits beim ersten Durchlauf erfolgen muss, weil ich sonst nachfolgende Blöcke gar nicht korrekt identifizieren kann.
BastiL
User
Beiträge: 135
Registriert: Montag 7. Juli 2008, 20:22

... ich habe gerade mal dazwischen eine Frage zur Umsetzung. Ich habe das File in einem Rutsch in den Speicher geladen und gehe nun den String char für char durch. Sobald ein neuer Block beginnt bleibe ich an der öffnenden Klammer stehen:

Code: Alles auswählen

(Ordnungszahl (ASCII_HEADER) (Binärkrams)) 
Die Ordnungszahl lese ich nun aus, indem ich einen Positionszähler eingeführt habe, der die aktuelle Position im String beinhaltet. Mittels

Code: Alles auswählen

string[positionszaehler:positionszaehler + 2]
bekomme ich so die Ordnungszahl durch "Vorauslesen" und kann sie mit Werten aus einer Tabelle vergleichen. Ich weiss nicht ob das die beste Methode ist, aber sie funktioniert auf jeden Fall. Schwierig ist es jetzt, den Header vorauszulesen. Den muss ich aber auch gelesen haben, bevor ich den Binärkrams einlesen kann. Die Position der öffnenden Klammer des Headers kenne ich, danach folgt eine variable Anzahl an Ganzzahlen (leerzeichegetrennt) und eine schließende Klammer. Ich kenne also die Position der schließenden Klammer nicht genau. Wie könnte ich das am geschicktesten einlesen?

Danke.
BlackJack

Kannst Du nicht einfach ganz normal die schliessende Klammer vom Header suchen? Dann weisst Du wie lang der ist.
BastiL
User
Beiträge: 135
Registriert: Montag 7. Juli 2008, 20:22

BlackJack hat geschrieben:Kannst Du nicht einfach ganz normal die schliessende Klammer vom Header suchen? Dann weisst Du wie lang der ist.
Doch im Prinzip schon. aber ich stehe gerade auf dem Schlauch was die Implementierung angeht. Bislang mache ich folgendes:

Code: Alles auswählen

# Einlesen der Datei in einem Rutsch
file = f.read()

# Zeichenweise der Datei entlangwandern und analysieren
for c in file
    pos = pos + 1
    if c == "("  and level == 0:
        if file[pos:pos + 2] == "Ordnungszahl1":
        # Blocktyp 1
        elif file[pos:pos + 2] == "Ordnungszahl2":
        # Blocktyp 2
        level = level + 1
    elif c == ")"
        level = level - 1
Damit geht es jetzt sehr schlecht, innerhalb der inneren if-Bedingungen weiterzusuchen, da das ganze ja innerhalb eines loops über alle Zeichen steht. Irgendwie müsste ich das geschickter machen, aber mir fehlen gerade die Ideen. Ich hätte gerne die Positionen der Blöcke (Anfang und Ende von Block und Header) als Pointer auf den String gespeichert, auch da weiss ich noch nicht so genau wie ich das machen könnte.
Freue mich über vorschläge. Danke.
Antworten