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

C语言open函数疑问:为何需重新打开文件才能配合execve工作

为什么关闭并重开文件后execve才能读取到内容?

我尝试用C语言实现类似<<(heredoc)的功能,练习open函数的使用,编写了如下代码:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    int in_fd = open("here_doc.tmp", O_CREAT | O_RDWR | O_TRUNC, 0644);
    int out_fd = open("outfile", O_CREAT | O_RDWR | O_APPEND, 0644);
    
    write(in_fd, "hello 1\n", 8);
    write(in_fd, "Pello 1\n", 8);
    write(in_fd, "Yello 1\n", 8);


/* ********* 我想知道下面两行为何是必需的 ******* */
    close(in_fd);
    in_fd = open("here_doc.tmp", O_RDWR, 0644);
  
    dup2(in_fd, 0);
    dup2(out_fd, 1);
    close (in_fd);
    close (out_fd);
    
    char *argv[]= {"cat", NULL};
    execve("/bin/cat", argv, NULL);
}

原本我以为只需要调用一次open就能完成,但发现直接使用第一次open的文件描述符时,execve调用的cat读不到文件内容,必须加上注释里的关闭并重开操作才能正常工作,请问这是为什么?


核心原因:文件偏移量的位置问题

当你第一次打开文件并执行三次write操作后,文件的当前偏移量已经移动到了文件末尾。此时如果直接把这个文件描述符通过dup2设置为标准输入(fd=0),cat程序从这个偏移位置开始读取,自然读不到任何内容——因为已经到文件结尾了。

而关闭文件再重新打开的操作,会把文件的偏移量重置到文件开头,这时候cat从开头读取,就能获取到之前写入的所有内容了。

替代方案:无需关闭重开的方法

其实不用关闭重开,直接调用lseek函数把偏移量移回文件开头即可,效果完全一样:

// 替换close和重新open的两行,改成下面这行
lseek(in_fd, 0, SEEK_SET);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:23:13