Strukturdefinition für binäre Dateien

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
Thomas W.
User
Beiträge: 17
Registriert: Sonntag 9. April 2006, 08:36
Wohnort: Halle (Saale)

Dienstag 11. September 2007, 14:01

Ich arbeite gerade mit binären Daten in Dateien. Den Zugriff regele ich über Strings, in die ich vor dem Schreiben meine Werte mit »pack« aus dem Modul »struct« komprimiere bzw. aus denen ich sie mit »unpack« extrahiere.

Dabei stört mich stört ein klein wenig, dass »unpack« mir ein Tuple zurückliefert. Ich kann das Tuple natürlich problemlos auswerten, würde aber lieber mit Schlüsselwörtern anstelle der Indexnummer auf die einzelnen Werte zugreifen, z.B. so wie in einem Dictionary.

Gibt es dafür eine Möglichkeit?
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Dienstag 11. September 2007, 16:10

Hi

Ganze Structures kannst du auch einfach mit Construct parsen und erstellen, da ist dann auch ein Zugriff per Name möglich.

Falls du die Struktur postest kann ich dir eine Starthilfe geben wie es etwa mit Construct aussieht.

Gruss
BlackJack

Dienstag 11. September 2007, 16:19

Vielleicht ist ja das `construct`-Package etwas für Dich: http://construct.wikispaces.com/

Edit: Mist, zu spät. :-)
Thomas W.
User
Beiträge: 17
Registriert: Sonntag 9. April 2006, 08:36
Wohnort: Halle (Saale)

Dienstag 11. September 2007, 16:46

rayo hat geschrieben:Ganze Structures kannst du auch einfach mit Construct parsen und erstellen, da ist dann auch ein Zugriff per Name möglich.
Danke für den Hinweis. Ich werde mich mal damit beschäftigen.
rayo hat geschrieben:Falls du die Struktur postest kann ich dir eine Starthilfe geben wie es etwa mit Construct aussieht.
Es geht um eine Datei mit Tags. Der prinzipielle Aufbau ist - auf das notwendige verkürzt - so:

Code: Alles auswählen

Pos   Len   Typ   Beschreibung
---   ---   ---   -------------
x00   x04    4c   "feste Dateikennung"

x04   x__   ___   Datenblock mit folgendem Aufbau
      
      Off   Len   Typ   Beschreibung
      ---   ---   ---   ------------
      x00   x02     i   "Blockkennung", aus der der Inhalt und die Art der
                        nachfolgenden Daten hervorgeht
                        1 = Bearbeiter, 2 = Datum, ... , 9 = Koordinaten, ...
      x02   var   var   Daten, z.B. 2 Gleitzahlen "Rechtswert" und "Hochwert"
                        oder 1 String "Name" oder Zeitwert "Datum" oder ...

x__   ---   --    nächster Datenblock
Mit der Blockkennung steht jeweils fest, welche Daten folgen und wie groß der Datenblock ist. Eine kleine Schwierigkeit ergibt sich, da es einen Datenblock gibt, der in einer ersten Zahl (Integer) das Datenformat der folgenden Gleitkommazahlen definiert, also ob 2 Zahlen mit doppelter Genauigkeit oder 4 mit einfacher Genauigkeit folgen.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Dienstag 11. September 2007, 17:17

Hi


Hier mal ein kleines Beispiel:

Code: Alles auswählen

import construct as con


block1 = con.Struct("zahlen_block",
                    con.UNInt8("typ"),
                    con.Switch("values", lambda ctx: ctx['typ'],
                                   {
                                    0x00: con.StrictRepeater(2, con.NFloat32("")),
                                    0x01: con.StrictRepeater(4, con.NFloat64("")),
                                   }
                                  )
                   )

block2 = con.Struct("zweiter_block",
                    con.UNInt8("spam")
                   )

data_block = con.Struct("blocks",
                        con.UNInt16("typ"), # UNInt16 = Unsigned Native endian Integer 16Bit
                        con.Switch("block", lambda ctx: ctx['typ'],
                                   {
                                    0x00: block1,
                                    0x01: block2,
                                   }
                                  )
                       )

file_tag = con.Struct("",
                      con.Const(con.UNInt8("magic_byte"), 0x4C), #Const bedeutet fester Wert
                      con.OptionalGreedyRepeater(data_block) # Solange wiederholen bis es nicht mehr geht
                     )


container = file_tag.parse_stream(file_handle)
oder
container = file_tag.parse(data)


print container.blocks
Am besten schaust du mal das Tutorial an:
http://construct.wikispaces.com/tutorial

Gruss
Thomas W.
User
Beiträge: 17
Registriert: Sonntag 9. April 2006, 08:36
Wohnort: Halle (Saale)

Dienstag 11. September 2007, 17:43

Dankeschön für die schnelle Hilfe. Jetzt habe ich ja erst mal etwas zum Verdauen.
Antworten