一、魔数
这里的魔数并非程序猿随便定义的魔数。对于很多类型的文件,其起始的几个字节的内容是固定的(或是有意填充,或是本就如此)。根据这几个字节的内容就可以确定文件类型,因此这几个字节的内容被称为魔数 (magic number)。【百度百科】
在Python 中同样也可以使用魔数判断一个文件的类型,例如是否被压缩。例如以下代码:
import gzip import pickle ## global variable GZIP_MAGIC = b'\x1F\x8B' class Incident: def import_pickle(self, filename): try: fh = None fh = open(filename, 'rb') #Get the handle magic = fh.read(len(GZIP_MAGIC)) if magic == GZIP_MAGIC: #The file has been zipped fh.close() gzip.open(filename, 'rb') #Reopen the file with gzip else: fh.seek(0) #Adjust the handle to the beginning of the file ''' Deal with the file ''' return True except (EnvironmentError, pickle.UnpicklingError) as err: print("Error {0}".format(err)) return False finally: if fh is not None: fh.close()利用获取魔数与GZIP_MAGIC比对确定其文件是否被压缩,并选择打开文件的方式。一般来说,由于魔数没有统一的数据库,只能期望该魔数对于本程序是独一无二的,有时也会在文件类型的魔数后加入版本号。
二、struct模块
struct模块用于处理将一些数据转化为二进制数据bytes对象。常用为struct.Struct类,struct.pack、struct.unpack函数。
1、struct.Struct类
该类储存struct的格式规范(format),大致格式为“<{个数}{
标识符
}”,例如"<H16s"。
1) “<”表示little-endian字节顺序(常用),也有时使用>。
2) 个数可以通过重复写标识符来实现,例如2H等价于HH
3) 常用标识符如下:
b:8位有符号整数
B:8位无符号整数
h:16位有符号整数
H:16位无符号整数
i:32位有符号整数
I:32位无符号整数
q:64位有符号整数
Q:64位无符号整数
f:32位浮点数
d:64位浮点数
?:布尔型
s:字节字符串
这种存储方式类似于C中的struct,Struct即定义了一个结构体,可以利用这个结构体构造不同的结构(二进制存储)
2、struct.pack与struct.unpack函数
这两个函数互为逆函数,可以通过相同的格式规范相互转化。其中bytespack(Struct format, **args)即接受一个格式规范和若干个数据,返回一个二进制串。items = unpack(Struct format,bytes data),unpack将pack得到的二进制串可以按照格式转化为一个元组item返回。例如:
TWO_SHORT = struct.Struct("<2h")
data = TWO_SHORT.pack(11, -9)
items = TWO_SHORT.unpack(data)
与下面的代码
data = struct.pack("<2h", 11, -9) #dara = b'\x0b\x00\xf7\xff'
items = struct.unpack("<2h", data) #items = (11, -9)
两代码完全等价,同时可以利用format函数来动态调整struct的格式。