读取日志数据的二进制文件并使用int(python)输出到新文件

问题描述:

我一直致力于使用FATFS模块将传感器数据写入SD卡的嵌入式软件项目。数据的数据类型是uint32_t(4字节),输出是二进制文件。我想写一个Python脚本来读取二进制文件(和解析数据为int并写入到一个新的文件)。我当前的代码,读取日志数据的二进制文件并使用int(python)输出到新文件

def read(): 
with open("INPUT1.TXT", "rb") as binary_file: 
    # Read the whole file at once 
    data = binary_file.read() 
    print(data) 

也练就了我的十六进制值一大块,

b' \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \t \n \x0b \ 
x0c \r \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 
\x18 \x19 \x1a \x1b \x1c \x1d \x1e \x1f  \x01 \x02 \x03 
    \x04 \x05 \x06 \x07 \x08 \t \n \x0b \x0c \r \x0e \x0f 
\x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1 
b \x1c \x1d \x1e \x1f  ' 

当打印每4个字节,一些数据甚至丢失,

f = open("INPUT2.TXT", "rb") 
try: 
    bytes_read = f.read(4) 
    while bytes_read: 
     print(bytes_read) 
     bytes_read = f.read(4) 
finally: 
    f.close() 

给予结果的

b' '  #supposed to be \x00 
b'\x01 ' 
b'\x02 ' 
b'\x03 ' 
b'\x04 ' 
b'\x05 ' 
b'\x06 ' 
b'\x07 ' 
b'\x08 ' 
b'\t '  #supposed to be \x09 
b'\n '  #supposed to be \x0a 
b'\x0b ' 
b'\x0c ' 
b'\r '  #supposed to be \x0d 
b'\x0e ' 
b'\x0f ' 
b'\x10 ' 
b'\x11 ' 
b'\x12 ' 
b'\x13 ' 
b'\x14 ' 
b'\x15 ' 
b'\x16 ' 
b'\x17 ' 
b'\x18 ' 
b'\x19 ' 
b'\x1a ' 
b'\x1b ' 
b'\x1c ' 
b'\x1d ' 
b'\x1e ' 
b'\x1f ' 

但是whe n我在十六进制编辑器中读取二进制文件,所有的二进制文件看起来是正确的?!

如果我想一次读取4个字节,并写入一个新文件(int类型),我该如何实现它?

感谢,

亨利

+0

你使用的是Python 2还是3?有一些细微的差异。 – youngmit

+0

检查[this](http://www.asciitable.com/)为什么你认为你是“丢失”的数据,因为你不会错过任何我能告诉的信息 – jacoblaw

+0

@youngmit我正在使用python 3. – shjnlee

nums = [] 
with open("INPUT2.TXT", "rb") as file: 
    while byte: 
     byte = file.read(4) 
     nums.append(int.from_bytes(byte, byteorder="little")) 

这应该为python 3做。

它看起来像你的字节从你的例子翻转,所以我改变了字节顺序。如果他们没有翻转,那么将其改回大。

另一个奇怪的事情:它看起来像0x00变成b“”,而不是b“\ x00”。如果是这种情况,那么请改为:

nums = [] 
with open("INPUT2.TXT", "rb") as file: 
    while byte: 
     byte = file.read(4) 
     nums.append(int.from_bytes(byte.replace(b" ", b"\x00"), byteorder="little")) 

下面是您提供的示例的示例。

>>> test = [b' ', 
b'\x01 ', 
b'\x02 ', 
b'\x03 ', 
b'\x04 ', 
b'\x05 ', 
b'\x06 ', 
b'\x07 ', 
b'\x08 ', 
b'\t ', 
b'\n ', 
b'\x0b ', 
b'\x0c ', 
b'\r ', 
b'\x0e ', 
b'\x0f ', 
b'\x10 ', 
b'\x11 ', 
b'\x12 ', 
b'\x13 ', 
b'\x14 ', 
b'\x15 ', 
b'\x16 ', 
b'\x17 ', 
b'\x18 ', 
b'\x19 ', 
b'\x1a ', 
b'\x1b ', 
b'\x1c ', 
b'\x1d ', 
b'\x1e ', 
b'\x1f '] 

>>> for t in test: 
>>>  print(int.from_bytes(t.replace(b" ", b"\x00"), byteorder="little")) 
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
+0

谢谢你的回答。但是,我得到了与Gribouillis答案非常相似的结果。数字给我一个非常大的数字(无效的)[538976288,18882592,35659808,52437024,6914240,85991456,102768672,119545888,136323104,153100320,169877536,...]。你知道为什么吗? – shjnlee

+0

@shjnlee嘿,我刚刚更新它,应该与编辑 – jacoblaw

+0

非常感谢!第二个代码块按预期工作! – shjnlee

也许你可以用

for i in range(0, len(data), 4) 
    d = struct.unpack('I', data[i:i+4]) 
    print(d) 
+0

我试过了你的代码,解包后的数据是无效的(即538976288,538976258,...)。 – shjnlee

做到这一点如果是打包成一个二进制文件,我想你可以使用read()功能上的文件只是uint32_t的数字

num_list = [] 
with open("INPUT1.TXT", "rb") as binary_file: 
    byte_data = 0x1 # Initial placeholder for the loop 
    while byte_data: 
     byte_data = binary_file.read(4) # 4 being the number of bytes to read at a time 
     num_list.append(int(byte_data)) 
# Do something with num_list 
+0

转换int(byte_data)可能有不对的地方。我把一个try块,因为它抱怨一些异常,并打印num_list,但它是空的。 – shjnlee