解析二进制文件需要知道数据几个字节,什么型,
之后就按照循环解析每行就好了
比如我解析出来的数据第一列应该是时间,第二列应该是个编号,我的数据是8个字节是时间,int64型,第二列编号是1个字节,uint8型,然后就依次根据自己的数据读取字节数,之后循环读取,因为每行数据类型一样。
import struct
import csv
import datetime
#将二进制.bin频谱文件解析成csv
def read_binary_data(filename):
isOneLine = True
result =[]
with open(filename, 'rb') as f:
while True:
if isOneLine:
# 读取前8个字节为时间,int64型
DateTime = struct.unpack('q', f.read(8))[0]
milliseconds = DateTime # 假设 DateTime 是以毫秒表示的时间
# 将毫秒转换为 datetime 对象
dt = datetime.datetime.fromtimestamp(milliseconds / 1000.0)
# 将 datetime 对象格式化为指定格式的时间字符串
DateTime = dt.strftime('%H:%M:%S')
isOneLine = False
# 读取接下来的1个字节为光束编号,uint8型,无符号八位整数
iLOS = struct.unpack('B', f.read(1))[0]
print("iLOS:", iLOS)
# 读取接下来的1个字节为距离长度,char型,无符号八位整数
distance_lengths = struct.unpack('B', f.read(1))[0]
# 读取接下来的2个字节为频谱长度,uint16型
spectral_length = struct.unpack('H', f.read(2))[0]
# 读取接下来的5120个字节为频谱数据,uint32型
iSpectrum0 = []
for i in range(256):
va = struct.unpack('I', f.read(4))[0]
iSpectrum0.append(va)
if va < 0:
print("s")
# 将数据转换为字符串,元素之间用空格分隔
iSpectrum0 = ' '.join(str(element) for element in iSpectrum0)
iSpectrum1 = [struct.unpack('I', f.read(4))[0] for _ in range(256)]
iSpectrum2 = [struct.unpack('I', f.read(4))[0] for _ in range(256)]
iSpectrum3 = [struct.unpack('I', f.read(4))[0] for _ in range(256)]
iSpectrum4 = [struct.unpack('I', f.read(4))[0] for _ in range(256)]
iSpectrum5 = [struct.unpack('I', f.read(4))[0] for _ in range(256)]
iSpectrum6 = [struct.unpack('I', f.read(4))[0] for _ in range(256)]
iSpectrum7 = [struct.unpack('I', f.read(4))[0] for _ in range(256)]
iSpectrum8 = [struct.unpack('I', f.read(4))[0] for _ in range(256)]
iSpectrum9 = [struct.unpack('I', f.read(4))[0] for _ in range(256)]
iSpectrum1 = ' '.join(str(element) for element in iSpectrum1)
iSpectrum2 = ' '.join(str(element) for element in iSpectrum2)
iSpectrum3 = ' '.join(str(element) for element in iSpectrum3)
iSpectrum4 = ' '.join(str(element) for element in iSpectrum4)
iSpectrum5 = ' '.join(str(element) for element in iSpectrum5)
iSpectrum6 = ' '.join(str(element) for element in iSpectrum6)
iSpectrum7 = ' '.join(str(element) for element in iSpectrum7)
iSpectrum8 = ' '.join(str(element) for element in iSpectrum8)
iSpectrum9 = ' '.join(str(element) for element in iSpectrum9)
# 将时间和频谱保存为一行
row = [DateTime, iLOS, distance_lengths, spectral_length, iSpectrum0,iSpectrum1,iSpectrum2,iSpectrum3,iSpectrum4,iSpectrum5,iSpectrum6,iSpectrum7,iSpectrum8,iSpectrum9]
result.append(row)
# 如果没有更多的数据,退出循环
z = f.read(8)
if not z:
break
DateTime = struct.unpack('q', z)[0]
milliseconds = DateTime # 假设 DateTime 是以毫秒表示的时间
# 将毫秒转换为 datetime 对象
dt = datetime.datetime.fromtimestamp(milliseconds / 1000.0)
# 将 datetime 对象格式化为指定格式的时间字符串
DateTime = dt.strftime('%H:%M:%S')
print(DateTime)
# 将读取到的数据保存到CSV文件
return result
with open('F:/2023121406_1.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['DateTime', 'iLOS', 'Distance lengths', 'Spectral length', 'iSpectrum0', 'iSpectrum1', 'iSpectrum2', 'iSpectrum3', 'iSpectrum4', 'iSpectrum5', 'iSpectrum6', 'iSpectrum7', 'iSpectrum8', 'iSpectrum9']) # 写入标题行
lists = read_binary_data('F:/2023121406.bin')
for row in lists:
writer.writerow(row) # 写入数据行