2010-06-17 3 views
15

sto aprendo un file binario in questo modo:manipolazione dei dati binari in Python

file = open("test/test.x", 'rb') 

e la lettura in linea ad una lista. Ogni riga assomiglia un po 'a:

'\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n' 

Ho difficoltà a manipolare questi dati. Se provo a stampare ogni riga, Python si blocca ed emette dei bip (penso che ci sia un codice bip binario lì da qualche parte). Come faccio ad usare questi dati in modo sicuro? Come posso convertire ciascun numero esadecimale in decimale?

risposta

23

Per stamparlo, si può fare qualcosa di simile:

print repr(data) 

Per il tutto come esadecimale:

print data.encode('hex') 

Per il valore decimale di ciascun byte:

print ' '.join([str(ord(a)) for a in data]) 

Per decomprimere gli interi binari, ecc. Dai dati come se provenissero originariamente da una struttura in stile C, guarda il modulo struct.

+0

Grazie! Questo è quello che stavo cercando! –

1

Si sta tentando di stampare i dati convertiti in caratteri ASCII, che non funzioneranno.

È possibile utilizzare in modo sicuro qualsiasi byte dei dati. Se si desidera stampare come un esadecimale, guarda le funzioni ord e hex/

2

Come il theatrus menzionato, ord e hex potrebbero aiutarti. Se si desidera provare a interpretare una sorta di dati binari strutturati nel file, il modulo struct potrebbe essere utile.

+2

+1 per struct. Il modo giusto per interpretare dati binari confezionati. –

3

\xhh is the character with hex value hh. Altri caratteri come . e `~ 'sono caratteri normali.

L'iterazione su una stringa fornisce i caratteri al suo interno, uno alla volta.

ord(c) will return an integer representing the character. E.g., ord('A') == 65.

Questo stamperà i numeri decimali per ogni personaggio:

s = '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n' 
print ' '.join(str(ord(c)) for c in s) 
+2

Si noti che \ x07 è quel carattere ASCII BEL. Questo è ciò che sta causando il beep. – dan04

1

Stai usando read() o readline()? Si dovrebbe usare read(n) per leggere n byte; readline() leggerà fino a quando non raggiunge una nuova riga, che il file binario potrebbe non avere.

In entrambi i casi, tuttavia, viene restituita una stringa di byte, che può essere stampabile o caratteri non stampabili, e probabilmente non è molto utile.

Quello che si desidera è ord(), che converte una stringa di un byte nel valore intero corrispondente. read() dal file un byte alla volta e chiamare ord() sul risultato, o scorrere l'intera stringa.

2

I dati binari vengono raramente divisi in "righe" separate da "\ n".Se lo è, avrà un meccanismo di escape implicito o esplicito per distinguere tra '\ n' come un terminatore di riga e '\ n' come parte dei dati. Leggere un file come le linee ciecamente senza conoscenza del meccanismo di fuga è inutile.

per rispondere alle vostre preoccupazioni specifiche:

'\ x07' è il carattere BEL ASCII, che in origine era per suonare il campanello su una telescrivente.

È possibile ottenere il valore intero di un byte "b" facendo ord(b).

TUTTAVIA, per elaborare correttamente i dati binari, è necessario sapere quale sia il layout. Puoi avere interi con segno e senza segno (di dimensioni 1, 2, 4, 8 byte), numeri decimali, numeri decimali di lunghezze variabili, stringhe di lunghezza fissa, stringhe di lunghezza variabile, ecc. La complicazione aggiunta viene dal fatto che i dati siano registrati nella moda bigendiana o nella moda littleendian. Una volta che hai compreso tutto quanto sopra (o hai ottime congetture informate), lo Python struct module dovrebbe essere in grado di essere utilizzato per tutti o gran parte dell'elaborazione; il ctypes module potrebbe anche essere utile.

Il formato dati ha un nome? Se è così, dicci; potremmo essere in grado di indicarti codice o documenti.

Si chiede "Come faccio a utilizzare questi dati in modo sicuro?" che pone la domanda: per cosa la vuoi usare? Che manipolazioni vuoi fare?