使用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作为格式说明符,仍然无效。
问题原因与解决方法
文件偏移指针位置错误
写完文件后,文件的偏移指针停留在文件末尾,此时直接调用read会从末尾开始读取,自然读不到有效数据。需要在写入后调用lseek(fileHandle, 0, SEEK_SET)将指针移回文件开头,再执行读取操作。打开文件的标志冲突
O_APPEND标志会强制每次写操作都将文件指针移到末尾,虽然这里写完立即读取,但该标志属于多余配置,可能干扰文件指针的控制,建议移除。格式说明符不匹配
unsigned long类型对应的printf格式符是%lu,原代码中使用%d会导致输出解析错误,即使读取到正确数据也无法正常显示,必须改用%lu。缺失错误检查
原代码没有检查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
相关产品推荐
相关产品推荐

