FAT32 RAW文件提取JPG报错,如何确定数据块大小并统计占用块数
问题解答
一、获取RAW镜像中FAT32文件系统实际数据块(簇)大小
FAT32的簇大小(也就是你说的实际数据块大小)存储在文件系统的引导扇区(DBR,DOS Boot Record)中,读取逻辑如下:
- 如果你的RAW镜像包含完整磁盘分区表:先读取LBA0地址的MBR,解析分区表获取FAT32分区的起始扇区号,跳转到对应偏移后再读取DBR
- 如果是纯FAT32分区镜像:直接读取镜像0偏移处的DBR即可
DBR中相关参数偏移: - 偏移
0x0B:2字节,每扇区字节数(通常是512,也可能是4096等) - 偏移
0x0D:1字节,每簇包含的扇区数
两个参数相乘就是FAT32的实际簇大小,也就是文件存储的最小分配单元大小。
二、统计单个文件占用的数据块总数量
分两种统计逻辑:
- 逻辑占用块数:找到文件对应的目录项,读取目录项中存储的文件实际字节大小,按公式
(文件大小 + 簇大小 - 1) / 簇大小向上取整即可得到文件需要占用的最小块数 - 实际分配块数:遍历FAT表中该文件对应的簇链,统计簇链的节点总数,就是实际分配给该文件的块数(如果文件有碎片化,这个数值会和逻辑占用块数一致,但是簇在磁盘上不连续)
现有代码段错误修复说明
你遇到的段错误和数据块大小不匹配无关,是代码本身存在多处严重问题:
- 空指针访问:如果镜像中没有找到任何JPG文件,
out指针始终为NULL,循环结束后直接执行fclose(out)会触发空指针访问崩溃,需要加非空判断:
if (out != NULL) { fclose(out); }
- 二进制文件打开方式错误:你使用
"r"和"w"打开文件,在Windows平台下会触发文本模式解析,把二进制中的0x1A识别为文件结束符,还会自动转换换行符,导致读取到的内容和实际镜像不一致,必须使用二进制模式打开:
FILE *file = fopen(argv[1], "rb"); out = fopen(filename, "wb");
- 写入长度错误:
fread返回值是实际读取到的字节数,当读到镜像末尾时可能不足512字节,你还是固定写512字节会导致输出的JPG末尾多出来无效内容,应该按实际读取长度写入:
size_t read_len = fread(buffer, sizeof(BYTE), sizeof(buffer), file); while (read_len > 0) { // 匹配JPG签名逻辑不变 // 写入的时候用read_len代替sizeof(buffer) if (out != NULL) { fwrite(buffer, sizeof(BYTE), read_len, out); } read_len = fread(buffer, sizeof(BYTE), sizeof(buffer), file); }
另外你固定按512字节读取的逻辑,只有当簇大小是512的整数倍时才能正确匹配到JPG签名,如果实际簇大小更大,可能出现JPG签名跨两次读取的情况,导致匹配失败,建议读取的块大小设置为读取到的实际簇大小。
内容的提问来源于stack exchange,提问作者Juan
相关产品推荐
相关产品推荐

