二进制文件读取以及文件处理常见问题

本文介绍了使用二进制文件的优势,尤其是在存储数字和进行计算时的速度提升。此外,详细讲解了Python基础文件处理方法,包括读写操作,并展示了如何使用CRC32校验功能,特别是在处理二进制数据时的注意事项。
摘要由CSDN通过智能技术生成

1.为什么我们要使用二进制文件。原因大概有三个:


 (1)二进制文件比较节约空间,这两者储存字符型数据时并没有差别。但是在储存数字,特别是实型数字时,二进制更节省空间,比如储存 Real*4 的数据:3.1415927,文本文件需要 9 个字节,分别储存:3 . 1 4 1 5 9 2 7 这 9 个 ASCII 值,而二进制文件只需要 4 个字节(DB 0F 49 40)
 (2)内存中参加计算的数据都是用二进制无格式储存起来的,因此,使用二进制储存到文件就更快捷。如果储存为文本文件,则需要一个转换的过程。在数据量很大的时候,两者就会有明显的速度差别了。
 (3)就是一些比较精确的数据,使用二进制储存不会造成有效位的丢失。
  通常情况下,我们保存数据到文件是默认文本文件的方式。以数字1297为例,在将其保存到文本文件中时,其被格式化为字符串的形式保存,如图1所示为此刻的存储方式。而将其以二进制的形式保存时,其最大只占用两个字节。

2.Python 基础文件处理方法:

读写:
with open('data.txt', 'r') as f:
    data = f.read()
    print('context: {}'.format(data))
参数为文件名(若不在工作区,建议加上地址,中间隔‘\’)
也可使用进行写入操作
f = open('file.txt','w')

获取目录列表:
.
├── file1.py
├── file2.csv
├── file3.txt
├── sub_dir
│   ├── bar.py
│   └── foo.py
├── sub_dir_b
│   └── file4.txt
└── sub_dir_c
    ├── config.py
    └── file5.txt
可以使用:
import os
entities = os.listdir('my_directory')

3.Python 操作二进制文件:

直接上代码:

f = open("C:/Users/Nagisa/Desktop/Winhex/test000.bin",'rb')
f.seek(0,0)
while True:
    t_byte = f.read(1)
    if len(t_byte) == 0:
        break
    else:
        list_data.extend(bytes(t_byte))

读:‘r’     写:‘w’

特别提醒:list_data是通过bytearray函数方法生成的byte类数组,虽然当你打印bytearray中的个体元素类型时,编译器会告诉你是int型,但是当你打印多个相连元素,编译器会自动处理成bytes型的数据串,这也是我们为什么会选用bytearray而不是直接凭空生成一个数组的原因,当你直接使用空数组逐字读取文件时,会处理成一个字符串数组。

list_data=bytearray()

memory=bytearray()


def calculate_crc32(list_data,start):
    memory.clear()
    memory1 = bytearray()
    memory1.clear()
    count=0
    now=start
    flag=0
    while count<13:
        if(now>=len(list_data)):
            return -1
        if list_data[now]==1 and flag==0:
            flag=1
            memory.extend(bytes(list_data[now]))
            memory1.append(list_data[now])
            count+=1
            list_data[now]=0x0B;
            #print(list_data[now])
        elif flag==1:
            memory.extend(bytes(list_data[now]))
            memory1.append(list_data[now])
            count+=1
            #print(list_data[now])
        now+=1
    memory1[0]=0x0B;
    #print(memory1[1])
    hex_data = [hex(x) for x in memory1]
    #print(hex_data)
    byte_data = bytes(int(x, 16) for x in hex_data)
    #print(byte_data)
    crc_value = zlib.crc32(memory1)
    byte_array = [(crc_value >> (8 * i)) & 0xFF for i in range(4)]
    crc_hex = hex(crc_value)[2:].upper()
    #print(crc_hex)
    #print(memory1)
    j=0
    hex_value=[]
    hex_value.clear()
    if(len(crc_hex)==7):
        hex_string = crc_hex[0:1]
        hex_value.append(int(hex_string, 16))
        for i in range(1, len(crc_hex), 2):
            hex_string = crc_hex[i:i+2]
            hex_value.append(int(hex_string, 16))
    elif(len(crc_hex)==8):
        hex_string = crc_hex[0:2]
        hex_value.append(int(hex_string, 16))
        for i in range(2, len(crc_hex), 2):
            hex_string = crc_hex[i:i+2]
            hex_value.append(int(hex_string, 16))
    for i in range(len(hex_value)):
        list_data[now]=(hex_value[3-i])
        now+=1
    
    return now
这里引用了之前手搓的CRC32校验的一段代码:
其实重点代码就只有:
    memory1 = bytearray()
    memory1[0]=0x0B;
    #print(memory1[1])
    hex_data = [hex(x) for x in memory1]
    #print(hex_data)
    byte_data = bytes(int(x, 16) for x in hex_data)
    #print(byte_data)
    crc_value = zlib.crc32(memory1)
    byte_array = [(crc_value >> (8 * i)) & 0xFF for i in range(4)]
    crc_hex = hex(crc_value)[2:].upper()
    #print(crc_hex)
zlib.crc32函数需要传入types数组型,bytearray直接传入即可,返回一个32位无符号整数
然后需要特别注意的是:
       当你处理完整数,将他们添加进bytearray数组里后,一定要检查第一个数据,如果它只有一位,那么它会自动省略掉前面那个0,导致你的数据错位!!(别问我是怎么知道的QAQ)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值