2017-07-27 5 views
0

Ich habe eine .Raw-Datei mit einem 52 Zeilen HTML-Header, gefolgt von den Daten selbst. Die Datei ist codiert in Little-Endian 24bit signiert und ich möchte die Daten in Ganzzahlen in einer ASCII-Datei konvertieren. Ich benutze Python 3.Konvertieren Little-Endian 24-Bit-Datei in ein ASCII-Array

Ich habe versucht, die gesamte Datei mit dem folgenden Code in this post gefunden 'auspacken':

import sys 
import chunk 
import struct 

f1 = open('/Users/anais/Documents/CR_lab/Lab_files/labtest.raw', mode = 'rb') 
data = struct.unpack('<i', chunk + ('\0' if chunk[2] < 128 else '\xff')) 

Aber ich bekomme diese Fehlermeldung:

TypeError: 'module' object is not subscriptable 

EDIT

Es scheint das besser zu sein:

data = struct.unpack('<i','\0'+ bytes)[0] >> 8 

Aber ich immer noch eine Fehlermeldung erhalten:

TypeError: must be str, not type 

leicht zu beheben nehme ich an?

+0

Können Sie das Ergebnis von 'f1.read()' posten? – Tomalak

+1

1) Screen Dumps sind hier nicht willkommen: großer Speicherplatz, keine Wiederverwendung, nicht durchsuchbar 2) Das Problem ist das * Chunk * Modul. Wahrscheinlich eine Namenskollision zwischen dem Modulnamen und der gewählten Instanzvariable. Oder hast du vergessen, etwas mit der Klasse * Chunk * zu instanziieren? – guidot

+0

Sie müssen zuerst die Binärdaten aus dem HTML-Code trennen. Verwenden Sie nicht 'bytes' als Variablennamen, da dieser Konflikt mit Pythons eigenen 'bytes'-Typ –

Antwort

0

Das ist keine nette Datei in Python zu verarbeiten! Python eignet sich hervorragend für die Verarbeitung von Textdateien, da es sie in großen Blöcken in einem internen Puffer liest und dann auf Zeilen iteriert, aber Sie können nicht einfach auf Binärdaten zugreifen, die nach dem Lesen von Text auf diese Weise kommen. Darüber hinaus unterstützt das Modul struct keine 24-Bit-Werte.

Der einzige Weg, den ich mir vorstellen kann, ist die Datei ein Byte zu lesen, zuerst 52 Mal ein Ende der Zeile zu überspringen, dann Bytes 3 zu einer Zeit zu lesen, verketten sie in einem 4 Byte Byte-String und entpacken Sie es.

Möglicher Code könnte sein:

eol = b'\n'   # or whatever is the end of line in your file 
nlines = 52   # number of lines to skip 

with open('/Users/anais/Documents/CR_lab/Lab_files/labtest.raw', mode = 'rb') as f1: 

    for i in range(nlines):  # process nlines lines 
     t = b''     # to store the content of each line 
     while True: 
      x = f1.read(1)  # one byte at a time 
      if x == eol:   # ok we have one full line 
       break 
      else: 
       t += x   # else concatenate into current line 
     print(t)     # to control the initial 52 lines 

    while True: 
     t = bytes((0,))    # struct only knows how to process 4 bytes int 
     for i in range(3):   # so build one starting with a null byte 
      t += f1.read(1) 
     # print(t) 
     if(len(t) == 1): break  # reached end of file 
     if(len(t) < 4):    # reached end of file with uncomplete value 
      print("Remaining bytes at end of file", t) 
      break 
     # the trick is that the integer division by 256 skips the initial 0 byte and keeps the sign 
     i = struct.unpack('<i', t)[0]//256 # // for Python 3, only/for Python 2 
     print(i, hex(i))      # or any other more useful processing 

Bemerkung: über Code geht davon aus, dass Ihre Beschreibung von 52 Zeilen (von einem Ende der Leitung beendet) wahr ist, aber das gezeigte Bild denken lassen, dass letzte Zeile nicht. In diesem Fall sollten Sie zuerst 51 Zeilen zählen und dann den Inhalt der letzten Zeile überspringen.

def skipline(fd, nlines, eol): 
    for i in range(nlines):  # process nlines lines 
     t = b''     # to store the content of each line 
     while True: 
      x = fd.read(1)  # one byte at a time 
      if x == eol:   # ok we have one full line 
       break 
      else: 
       t += x   # else concatenate into current line 
     # print(t)     # to control the initial 52 lines 

with open('/Users/anais/Documents/CR_lab/Lab_files/labtest.raw', mode = 'rb') as f1: 
    skiplines(f1, 51, b'\n')  # skip 51 lines terminated with a \n 
    skiplines(f1, 1, b'>')  # skip last line assuming it ends at the > 

    ... 
+0

Vielen Dank für Ihre Antwort, begleitet von einer ausführlichen Erklärung, die für mich notwendig war, da ich gerade mit der Programmierung anfange. Ich habe die Ergebnisse mit einem Matlab-Code überprüft und keine Überraschung, es funktioniert perfekt! Danke noch einmal !! – ananas

Verwandte Themen