C语言写入文件后read返回0 无法读取内容完成文件复制
问题核心原因
你写入源文件后,文件描述符对应的读写偏移量停在了写入内容的末尾,直接调用read会从当前偏移位置也就是文件末尾开始读取,自然读不到任何数据,返回0。
代码里的其他隐藏问题
filedup函数中validfname检查传入了未定义的变量fname,属于笔误,正常编译阶段就会抛出未定义标识符错误,应该传入参数cpyfile。- 存储
read返回值的变量rd定义为size_t(无符号整型),而read出错时会返回-1,转成无符号类型会变成极大的正整数,会导致循环逻辑异常。 - 单字节读写效率极低,且没有对
write的返回值做校验,极端场景下会出现写入不全、错误被忽略的问题。 - 循环结束后没有判断
read是否因为出错(返回-1)终止,会把读失败的场景误判为复制成功。 main函数中调用strdup分配的内存没有释放,存在内存泄漏。
修复后代码
#include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <stdio.h> // 补全原代码依赖的工具函数实现 int validfname(char *name) { return name != NULL && name[0] != '\0'; } void putstr_fd(char *str, int fd) { write(fd, str, strlen(str)); free(str); } int filedup(int fd1, char *cpyfile) { int fd; ssize_t rd; char buff[1024]; // 用1KB缓冲区替代单字节读写,提升效率 if (fd1 < 0 || fd1 > OPEN_MAX) return (-1); if (!validfname(cpyfile)) return (-1); fd = open(cpyfile, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) return (-1); // 核心修复:将源文件的读写偏移量重置到文件起始位置 if (lseek(fd1, 0, SEEK_SET) == -1) { close(fd); return (-1); } rd = read(fd1, buff, sizeof(buff)); while (rd > 0) { ssize_t wr = write(fd, buff, rd); if (wr != rd) { close(fd); return (-1); } rd = read(fd1, buff, sizeof(buff)); } if (rd == -1) { close(fd); return (-1); } close(fd); return (0); } int main(void) { int fd; fd = open("/tmp/cpyfromfile", O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd == -1) return (-1); putstr_fd(strdup("hello world\n"), fd); if (filedup(fd, "cpyfile") == -1) { perror("file duplicate failed"); close(fd); return (-1); } close(fd); return (0); }
验证
编译运行修复后的代码,检查目标文件可以看到内容正常复制:
$ gcc -o dup_test dup_test.c $ ./dup_test $ cat cpyfile hello world
内容的提问来源于stack exchange,提问作者interesting
相关产品推荐
相关产品推荐

