如何从文件中读取字节

时间:2014-02-28 23:33:18

标签: python file python-3.x

我正在尝试从.lrf文件中读取一些元数据的长度。 (与程序LoLReplay一起使用)

关于这些文件并没有真正的文档,但我已经想出如何在C ++中执行此操作。我试图在python中重新编写项目有多种原因,但我遇到了一个错误。

首先解释一下,.lrf文件以这种格式在文件的开头立即包含元数据:

  • 前4个字节用于我不知道的事情。

  • 接下来的4个字节以十六进制的形式存储元数据的长度,直到元数据结束,之后是重放的实际内容。

  • 初始8字节后的
  • 字节是json格式的元数据

我遇到的问题实际上是读取元数据长度。这是我目前的功能:

def getMetaLength(self):
    try:
        file = open(self.file,"r")
    except IOError:
        print ("Failed to open file.")
        file.close()
    #We need to skip the first 4 bytes.
    file.read(4)
    mdlength = file.read(4)
    print(hex(mdlength))
    file.close()

当我调用此函数时,shell返回一个回溯声明:

    Traceback (most recent call last):
    File "C:\Users\Donald\python\lolcogs\lolcogs_main.py", line 6, in <module>
    lolcogs.getMetaLength()
    File "C:\Users\Donald\python\lolcogs\LoLCogs.py", line 20, in getMetaLength
    file.read(4)
    File "C:\Python32\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
    UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 3648:       character maps to <undefined>

我最好的猜测是read()试图读取以某种unicode格式编码的字符,但这些肯定只是我试图读取的字节。有没有办法将这些作为字节读取?此外,当您尝试读取文件时,是否有更好的方法可以跳过字节?

3 个答案:

答案 0 :(得分:2)

在Python 3中,默认情况下使用系统编码以文本模式打开文件。您需要以二进制模式打开文件:

file = open(self.file, 'rb')

您将遇到的另一个问题是file.read(4)将为您提供一个包含4个字节的字符串(hex函数无法理解)。你可能想要一个整数。为此,请参阅int.from_bytes,或者更一般地,参考struct module。然后你可以用十六进制格式打印那个数字:

mdlength = int.from_bytes(file.read(4), byteorder='big')
print(hex(mdlength))

答案 1 :(得分:2)

二进制文件应以二进制模式处理:

f = open(filename, 'rb')

对于跳过字节,我通常使用文件seek(SEEK_CUR或SEEK_SET),或者我只是做任意file.read(n)如果我不想打扰形式。只有我真正想要寻求的是我想跳到一个特定的位置。

解释二进制数据我只是坚持使用struct模块提供的解包方法,这样可以很容易地定义是否要将字节序列解释为int,float,char等。这就是如何我已经做了多年,所以也许有更有效的方法,如其他答案中描述的from_bytes方法。

使用struct模块,您可以执行

之类的操作
struct.unpack("3I", f.read(12))

一次读入3个(无符号)整数。因此,举例来说,如果您采用了逆向工程的格式,我可能只会说

unk, size = struct.unpack("2I", f.read(8))
data = f.read(size)

答案 2 :(得分:1)

您应该以二进制模式打开文件:open(filename, 'rb')