Binaer schreiben

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
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

Hi alle,

eigentlich recht leicht.
Ich muss einen ganz bestimmten filetyp schreiben koennen:
http://www.wadsworth.org/spider_doc/spi ... e_doc.html

Mein Versuch sieht wie folgt aus (Ausschnitt aus dem ganzen):

Code: Alles auswählen

def writeSpider(volume,filename):

    fileHandle = open(filename,'wb')
    
    fileHandle.write(int(volume.sizeZ())) #nslice
    fileHandle.write(int(volume.sizeX())) #nrows
    fileHandle.write(int(0)) #irec
    fileHandle.write(int(0)) #unused
    if volume.sizeZ() > 1:
        fileHandle.write(int(3)) #iform
    else:
        fileHandle.write(int(1)) #iform
        
    fileHandle.write(int(0)) #imami
    fileHandle.write(int(0)) #fmax
    fileHandle.write(int(0)) #fmin
    fileHandle.write(int(0)) #av
    fileHandle.write(int(-1)) #sig
    fileHandle.write(int(0)) #unused
    fileHandle.write(int(volume.sizeY())) #nsam


    for z in xrange(volume.sizeZ()):
        for x in xrange(volume.sizeX()):
            for y in xrange(volume.sizeY()):
                fileHandle.write(volume.getV(x,y,z))
                
    fileHandle.close()
Leider bekomme ich folgende Fehlermeldung:
fileHandle.write(int(volume.sizeZ())) #nslice
TypeError: argument 1 must be string or buffer, not int

Wie kann ich mit Python binaer schreiben so dass ich sicher bin dass ich 4Byte (int) 2Byte (Char) usw. verwende?

Cheerio!
deets

Zuerstmal: binaer schreiben heisst in Python strings schreiben. Im Gegensatz zu vielen anderen Sprachen speichert Python Strings mit einer expliziten Laengenangabe ab - und dadurch koenenn sie auch 0-Bytes enthalten.

Die Zahl 0x0000 ist also als String

Code: Alles auswählen

"\x00\x00"
Und das kannst du auch genau so schreiben.

Um diverse primitive Datentypen zu "Binaer'-Strings zu wandeln, gibt es das Modul struct:
import struct
print repr(struct.pack("i", 0))
deets

Kleiner Nachtrag: die ganzen fuerchterlich repetitiven Zeilen in deinem Code schreibst du dann natuerlich kompakter so:

Code: Alles auswählen

>>> struct.pack("iiiii", 0, 1, 2, 3, 4)
'\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'    
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

ok, also soll ich deiner meinung nach so schreiben :

fileHandle.write("\x00") #irec
fuer nuller schreiben

wie speichere ich aber normale zahlenwerte dass sie 32bit (int) lang sind?
wie

fileHandle.write(int(volume.sizeZ())) #nslice


checks nicht ganz. der string '9' ist kuerzer als '15' wobei beide doch theoretisch von einem byte dargestellt werden koennen ???
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

thomas15 hat geschrieben:checks nicht ganz. der string '9' ist kuerzer als '15' wobei beide doch theoretisch von einem byte dargestellt werden koennen ???
Nein, ersteres ist ein Byte, letzteres sind zwei. Und "9" ist auch nicht 9 sondern das ASCII-Zeichen fuer 9. Entweder du nutzt `chr` oder den von deets beschriebenen Weg. Nein vergiss ersteres und nutze `struct`.
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

In [6]: struct.pack('i',1)
Out[6]: '\x01\x00\x00\x00'

das letzte byte ist also mit 01 besetzt was auch ok ist.

hab jetzt aber den versuch gemacht:

Code: Alles auswählen

fileHandle.write(struct.pack("i", int(10)))
fileHandle.write(struct.pack("i", int(10)))
bekomme im hexedit der file fuer die ersten 16 bytes folgendes:

Code: Alles auswählen

00000000   0A 00 00 00  0A 00 00 00
sollte stimmen, oder?
BlackJack

@thomas15: Ja das stimmt. Die `int()`-Aufrufe sind aber total überlüssig.

Code: Alles auswählen

In [332]: 10
Out[332]: 10

In [333]: int(10)
Out[333]: 10
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

ok, nachdem ich also den hinweg verstanden habe, wie funktioniert dann binaeres lesen?

sorry dass ich hier so bloede fragen stelle aber ich bin in diesem fall C gewoehnt... find das bissl seltsam alles... :D
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

mit struct.unpack :)
hier sonst die Dokumentation: http://docs.python.org/library/struct.html
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

alles klaro, danke, schau ich mir morgen an.

write hat auf jeden fall schonmal funktioniert... danke an alle!

heimgehts
Antworten