2016-08-08 38 views
-1

Ich versuche, Code zu debuggen, einen früheren Praktikanten schrieb und ich habe einige Schwierigkeiten bei der Auflösung Dieses Problem mit Antworten von anderen Unicode-Fehler-Posts.UnicodeEncodeError: 'Ascii' Codec kann nicht codieren Zeichen u ' u0446' in Position 32: Ordnungszahl nicht im Bereich (128)

def dumpTextPacket(self, header, bugLog, offset, outfile): 
     bugLog.seek(offset) 
     data = bugLog.read(header[1])  # header[1] = size of the packet 
     outString = data.decode("utf-8","ignore") 
     if(header[3] == 8): # Removing ugly characters from packet that has bTag = 8. 
      outString = outString[1:] 
      outString = outString.strip('\0') # Remove all 'null' characters from text 
     outString = "{:.3f}".format(header[5]) + ' ms: ' + outString    # Append the timestamp to the beginning of the line 
     outfile.write(outString) 

Ich habe nicht viel Erfahrung mit Unicode, also würde ich wirklich zu schätzen alle Hinweise mit dieser Ausgabe:

Der Fehler wird in der letzten Zeile dieser Funktion gefunden!


bearbeiten: Mit Python 2.7 und darunter ist die gesamte Datei. Eine andere Sache, die ich erwähnen sollte, ist, dass der Code funktioniert, wenn einige Dateien analysiert werden, aber ich denke, dass es Fehler in anderen Dateien gibt, wenn der Zeitstempel zu groß wird?

In der main.py Datei rufen wir die Methode LogInterpreter.execute() auf, und die Traceback gibt den Fehler im Titel in der Zeile "outfile.write (outString)", die letzte Zeile in der Methode dumpTextPacket die in der execute-Methode genannt:

import sys 
import os 
from struct import unpack 
class LogInterpreter: 

def __init__(self): 
    self.RTCUpdated = False 
    self.RTCOffset = 0.0 
    self.LastTimeStamp = 0.0 
    self.TimerRolloverCount = 0 
    self.ThisTimeStamp = 0.0 

    self.m_RTCSeconds = 0.0 
    self.m_StartTimeInSec = 0.0 

def GetRTCOffset(self): 
    return self.m_RTCSeconds - self.m_StartTimeInSec 

def convertTimeStamp(self,uTime,LogRev): 
    TicsPerSecond = 24000000.0 

    self.ThisTimeStamp = uTime 
    self.RTCOffset = self.GetRTCOffset() 

    if int(LogRev) == 2: 
     if self.RTCUpdated: 
      self.LastTimeStamp = 0.0 
     if self.LastTimeStamp > self.ThisTimeStamp: 
      self.TimerRolloverCount += 1 
     self.LastTimeStamp = self.ThisTimeStamp 

    ULnumber = (-1 & 0xffffffff) 

    return ((ULnumber/TicsPerSecond)*self.TimerRolloverCount + (uTime/TicsPerSecond) + self.RTCOffset) * 1000.0 

########################################################################## 
# Information about the header for the current packet we are looking at. #         
########################################################################## 
def grabHeader(self, bugLog, offset): 
    ''' 
    s_PktHdrRev1 
    /*0*/ u16 StartOfPacketMarker; # uShort 2 
    /*2*/ u16 SizeOfPacket;  # uShort 2 
    /*4*/ u08 LogRev;    # uChar 1  
    /*5*/ u08 bTag;    # uChar 1  
    /*6*/ u16 iSeq;    # uShort 2 
    /*8*/ u32 uTime;    # uLong 4 
    ''' 
    headerSize = 12 # Header size in bytes 
    bType = 'HHBBHL' # codes for our byte type 
    bugLog.seek(offset) 
    data = bugLog.read(headerSize) 

    if len(data) < headerSize: 
     print('Error in the format of BBLog file') 
     sys.exit() 

    headerArray = unpack(bType, data) 
    convertedTime = self.convertTimeStamp(headerArray[5],headerArray[2]) 
    headerArray = headerArray[:5] + (convertedTime,) 
    return headerArray 

################################################################ 
# bTag = 8 or bTag = 16 --> just write the data to LogMsgs.txt # 
################################################################ 
def dumpTextPacket(self, header, bugLog, offset, outfile): 
    bugLog.seek(offset) 
    data = bugLog.read(header[1])        # header[1] = size of the packet 
    outString = data.decode("utf-8","ignore") 
    if(header[3] == 8):           # Removing ugly characters from packet that has bTag = 8. 
     outString = outString[1:] 
     outString = outString.strip('\0')       # Remove all 'null' characters from text 
    outString = "{:.3f}".format(header[5]) + ' ms: ' + outString # Append the timestamp to the beginning of the line 
    outfile.write(outString) 



def execute(self): 
    path = './Logs/' 
    for fn in os.listdir(path): 
     fileName = fn 
     print fn 
     if (fileName.endswith(".bin")): 
     # if(fileName.split('.')[1] == "bin"): 
      print("Parsing "+fileName) 
      outfile = open(path+fileName.split('.')[0]+".txt", "w")   # Open a file for output 
      fileSize = os.path.getsize(path+fileName) 
      packetOffset = 0 
      with open(path+fileName, 'rb') as bugLog: 
       while(packetOffset < fileSize): 
        currHeader = self.grabHeader(bugLog, packetOffset)  # Grab the header for the current packet 
        packetOffset = packetOffset + 12       # Increment the pointer by 12 bytes (size of a header packet) 
        if currHeader[3]==8 or currHeader[3]==16:     # Look at the bTag and see if it is a text packet 
         self.dumpTextPacket(currHeader, bugLog, packetOffset, outfile) 
        packetOffset = packetOffset + currHeader[1]    # Move on to the next packet by incrementing the pointer by the size of the current packet 
      outfile.close() 
      print(fileName+" completed.") 
+0

können Sie der Funktion auch einen Eingang hinzufügen? –

+0

Die Datei, in die Sie schreiben, wird wahrscheinlich mit dem ASCII-Codec geöffnet. Verwenden Sie Python 2 oder 3? –

+0

@DennisKuypers: Alternativ, wenn dies Python 2 ist und 'data' bereits ein' unicode' Objekt ist, codiert das Dekodieren implizit die Verwendung der Standard-Gebietsschema-Einstellungen (was oft ASCII bedeutet) vor der eigentlichen 'Dekodierung 'Schritt. Wir müssten allerdings das Traceback sehen, um sicher zu sein. – ShadowRanger

Antwort

0

Wenn Sie addieren sich zwei Strings mit einer von ihnen Unicode, Python 2 wird das Ergebnis auf Unicode zwingen.

>>> 'a' + u'b' 
u'ab' 

Da Sie data.decode verwendet wird outString Unicode sein.

Wenn Sie in eine Binärdatei schreiben, müssen Sie eine Byte-Zeichenfolge haben. Python 2 wird versuchen, Ihre Unicode-Zeichenfolge in eine Byte-Zeichenfolge zu konvertieren, aber es verwendet den allgemeinsten Codec, den es hat: 'ascii'. Dieser Codec schlägt bei vielen Unicode-Zeichen fehl, insbesondere bei solchen mit einem Codepunkt über '\u007f'. Sie können es selbst mit einem fähigen Codec kodieren, um dieses Problem zu erhalten:

outfile.write(outString.encode('utf-8')) 

Alles ändert mich in Python 3, die Sie Byte-Strings und Unicode-Strings mischen werden nicht zulassen, noch keine automatischen Konvertierungen versuchen.