You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:45:03