# hzfile **Repository Path**: hrpzcf/hzfile ## Basic Information - **Project Name**: hzfile - **Description**: 学习用,自定义二进制文件生成和读取。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-11-05 - **Last Updated**: 2024-10-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # hzfile 这是一个练习二进制读写时写的模块,比较简易。 ### 功能 1. 把一个目录下诸多文件打包合并成一个<.hz>文件,无加密,无压缩。 2. 把<.hz>文件内打包合并的文件原样提取出来,但不包含目录结构,可以全部提取,也可以按文件名提取。 ### 思路 1. 先设计一个<.hz>文件的格式规范,尽可能地把打包提取时会遇到的问题考虑进去。 2. 编写代码,按设计的规范使用二进制方式读写<.hz>文件,借助模块对整数和二进制字节码进行转换操作。 ### 格式规范 | | 储存的数据 | 储存的数据 | 储存单元的类型 | 储存单元的数量 | 总占用字节数 | | :------------------: | :--------------------: | :--------------------------------: | :-------------: | :------------: | :--------------: | | **文件头部信息** | 文件格式标识 | | unsigned char | 16 | 16 | | | 类型空间占用表 | 四个类型的空间占用大小(B, H, I, Q) | unsigned char | 4 | 4 | | | 格式版本信息 | | unsigned short | 4 | H * 4 | | | 预留空白字节 | | NA | NA | 255 | | | 被合并的文件总数 | | unsigned int | 1 | I * 1 | | **被合并的单个文件** | 文件大小 | | unsigned int | 1 | I * 1 | | | 文件名长度 | | unsigned int | 1 | I * 1 | | | 文件名字节串(包含'\0') | | unsigned char * | 1 | <文件名长度>的值 | | … | | | | | | | **被合并的文件数据** | 被合并的文件字节码 | | | | | | … | | | | | | ### 代码思路 1. 模块中包含一个类,类实例化时需要一个文件路径参数,当文件存在时,读取文件头部信息保存到类属性中。当文件不存在时,用默认的文件头部信息创建一个<.hz>文件。 2. 当读取一个已存在的<.hz>文件时,不可对文件进行写操作(比如用方法打包新的文件),只能对其进行读操作(比如用方法提取所有文件)。 3. 当创建一个不存在的<.hz>文件时,可以进行写操作(比如用方法打包新的文件),写操作后,只可进行读操作,不再允许写操作。 4. 限制写操作是因为设计格式规范时没考虑好(踩到的第一个坑),导致每次新的写操作都要对<.hz>文件全部读写一遍,浪费性能。 ### 模块使用 1. 安装模块,win平台:`py -m pip install -U hzfile` 2. 编写使用代码 ```python # coding: utf-8 from hzfile import HzFile hzf = HzFile(r"./myfile.hz") # r"./myfile.hz" 指向一个不存在的文件 # 后缀名是什么无关紧要,读取时是以文件头的文件格式标识判断格式是否正确的 hzf.merge(r"./pictures", recursion=False, bigok=False) # 参数1是一个目录路径,表示将该路径下的所有文件打包进myfile.hz文件 # 参数recursion表示是否递归搜索参数1目录下的子目录 # 参数bigok表示在当参数1下的文件大于4G时是否直接跳过,True表示直接跳过,False表示抛出Exception异常。 # 因为格式规范设计之初考虑性能问题,仅用一个unsigned int保存文件的大小信息(字节),也就是能表示大约4G大小。 print(hzf.fbom()) # 打印文件内所包含的文件的信息。 # 返回值格式为[(文件大小, 文件名字节串含'\0'长度, 文件名字符串), ...] print(hzf.fcnt()) # 打印文件内包含的文件数量 print(hzf.fver()) # 打印创建时使用的格式规范版本,是[a,b,c,d]形式,abcd均>=0, <=255。 print(hzf.ftypesize()) # 接受5个值:B, H, I, Q, None # 返回创建时使用的各类型数据的占用空间大小 hzf.extract(["a.txt", "b.jpg", "c.mp4"], dirpath=r"./files1", overwrite=False) # 按文件名提取文件 # 第一个参数是要提取的文件名列表 # 第二个参数dirpath是一个目录路径,可以是已存在或不存在的路径,提取出的文件将被保存到这个目录 # 第三个参数overwrite是是否覆盖同名文件,这个参数仅针对提取文件前dirpath中已存在的文件 # 对于中的同名文件,提取时会以的形式重命名文件,不会被覆盖 # 打包时的文件目录结构不会被打包,也就是说,无论打包多少层的目录内的文件,提取时都只会以一层目录(dirpath)保存 hzf.extractall(dirpath=r"./files2", overwrite=False) # 提取所有文件,参数同方法的最后两个参数 ```