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

使用read系统调用读取文件描述符数据出现垃圾值问题

问题:写入二进制文件后读取得到垃圾值或零

我在Visual Studio中进行Linux系统编程,部署到VirtualBox虚拟机。创建了一个包含10个unsigned long类型元素的数组,元素值为i*i,写入sample.bin文件后,读取时得到的却是垃圾值或零。

代码示例

#include <cstdio>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main() {

    unsigned long elements[10];
    for (int i = 0; i < 10; i++) {
        elements[i] = (unsigned long)(i * i);
    }

    int fileHandle = open("sample.bin", O_CREAT | O_TRUNC | O_RDWR | O_APPEND, 0777);

    int dataToFile = write(fileHandle, elements, 10 * sizeof(unsigned long));
    
    unsigned long readBuffer[10];
    
    int dataFromFile = read(fileHandle, readBuffer, 10 * sizeof(unsigned long));
    
    for (int i = 0; i < 10; i++) {

        printf("%d\t", readBuffer[i]);

    }

    return 0;
}

已尝试的方法

  • 将write函数修改为write(fileHandle, &elements, 10 * sizeof(unsigned long));,read函数也做同样修改,无效。
  • 使用%lu作为格式说明符,仍然无效。

问题原因与解决方法

  1. 文件偏移指针位置错误
    写完文件后,文件的偏移指针停留在文件末尾,此时直接调用read会从末尾开始读取,自然读不到有效数据。需要在写入后调用lseek(fileHandle, 0, SEEK_SET)将指针移回文件开头,再执行读取操作。

  2. 打开文件的标志冲突
    O_APPEND标志会强制每次写操作都将文件指针移到末尾,虽然这里写完立即读取,但该标志属于多余配置,可能干扰文件指针的控制,建议移除。

  3. 格式说明符不匹配
    unsigned long类型对应的printf格式符是%lu,原代码中使用%d会导致输出解析错误,即使读取到正确数据也无法正常显示,必须改用%lu。

  4. 缺失错误检查
    原代码没有检查open、write、read的返回值,无法快速定位操作是否失败。添加错误检查能帮助排查文件操作中的异常。

修正后的代码

#include <cstdio>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main() {

    unsigned long elements[10];
    for (int i = 0; i < 10; i++) {
        elements[i] = (unsigned long)(i * i);
    }

    // 移除O_APPEND标志
    int fileHandle = open("sample.bin", O_CREAT | O_TRUNC | O_RDWR, 0777);
    if (fileHandle == -1) {
        perror("open failed");
        return 1;
    }

    int dataToFile = write(fileHandle, elements, 10 * sizeof(unsigned long));
    if (dataToFile == -1) {
        perror("write failed");
        close(fileHandle);
        return 1;
    } else if (dataToFile != 10 * sizeof(unsigned long)) {
        printf("Warning: only wrote %d bytes\n", dataToFile);
    }

    // 将文件指针移回文件开头
    off_t seekResult = lseek(fileHandle, 0, SEEK_SET);
    if (seekResult == -1) {
        perror("lseek failed");
        close(fileHandle);
        return 1;
    }

    unsigned long readBuffer[10];
    int dataFromFile = read(fileHandle, readBuffer, 10 * sizeof(unsigned long));
    if (dataFromFile == -1) {
        perror("read failed");
        close(fileHandle);
        return 1;
    } else if (dataFromFile != 10 * sizeof(unsigned long)) {
        printf("Warning: only read %d bytes\n", dataFromFile);
    }

    for (int i = 0; i < 10; i++) {
        printf("%lu\t", readBuffer[i]);
    }
    printf("\n");

    close(fileHandle);
    return 0;
}

内容的提问来源于stack exchange,提问作者Jawad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:47:05