Linux下读取ext3文件系统字节查找MP3签名出现异常输出求助
问题原因及修正方案
核心错误点
- 缓冲区类型使用错误:你定义的
buffer是int类型,在绝大多数系统上占4字节内存,但read(fd, &buffer, 1)只往内存里写入了1个字节的磁盘数据,剩下的3字节是栈空间未初始化的随机垃圾值。你看到的5500/5600波动,本质就是这些随机高位垃圾值的变化,真正读到的磁盘字节只有最低的8位。 - 读取操作未做返回值校验:
read调用可能出现读取失败、短读取的情况,没有校验逻辑会导致你拿到无效数据也正常输出。 - 偏移逻辑不符合需求:你当前的循环是每间隔128MB(134217728字节)读取1个字节,完全跳过了绝大多数磁盘区域,无法完成逐块扫描查找MP3签名的需求。
- 额外注意:你执行的
dd if=/dev/zero of=/dev/sdc1需要root权限才能写入块设备,如果执行时没有加sudo、或者命令中断提前退出,就会导致磁盘区域没有被完全清零,也可能读到非0值。
修正后的代码示例
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> void ReadDataBlockTest(char* arg) { int fd; ssize_t read_ret; if((fd = open(arg, O_RDONLY)) < 0){ perror(arg); exit(EXIT_FAILURE); } // 示例:按4KB块大小逐块扫描(可根据实际磁盘块大小调整参数) const size_t block_size = 4096; unsigned char block_buf[block_size]; off_t offset = 0; // 可根据磁盘实际大小调整循环终止条件 while ((read_ret = read(fd, block_buf, block_size)) > 0) { for (size_t i = 0; i < read_ret; i++) { // 此处可添加MP3签名比对逻辑,MP3帧头签名通常为0xFFE开头(注意大端序) printf("偏移%ld: %02X\n", offset + i, block_buf[i]); } offset += read_ret; } if (read_ret < 0) { perror("读取磁盘失败"); } close(fd); } int main (int argc, char* argv[]) { if (argc < 2) { printf("用法: %s <磁盘设备路径>\n", argv[0]); return EXIT_FAILURE; } printf("argc : %d \nargv %s \n", argc, argv[1]); ReadDataBlockTest(argv[1]); return EXIT_SUCCESS; }
验证说明
修正后用unsigned char类型存储单字节,打印的时候只会输出读到的1字节内容,不会携带栈垃圾值,也就不会出现数值波动的问题。如果磁盘确实被完全清零,所有位置的输出都应该是00。
内容的提问来源于stack exchange,提问作者Sanika
相关产品推荐
相关产品推荐

