我能关闭文件而不关闭fd吗?

3

我用 fdopen(fd, "w+") 打开了一个 FILE *f,并且希望在使用 fclose(f) 关闭文件后保持 fd 打开状态。

有没有更好的方法实现这个功能?

我可以简单调用 fflush(f); free(f); 吗,这样做是否存在风险?

还是说有一种方式可以将内部的 fd 更改为无效值 -1,以便 fclose() 不能关闭 fd


4
我猜你可以使用dup(fileno(f)) - rodrigo
1
我理解你的立场,但我认为没有一种可移植的方法来实现你想要的。而且调用 free(f) 是一个非常糟糕的想法。此外,调用 dup() 是廉价的,肯定不比 fflush() 更昂贵。 - rodrigo
3
请具体说明“性能更重要”是什么意思。我建议尝试int fd2 = dup(fd); f = fdopen(fd2, "w+"); ... fclose(f);测量增加dup对性能的影响。请在问题中添加更多信息:您的用例是什么?为什么您需要使用fdopenfclose并保持fd打开状态?也许有不同的解决方案。 - Bodo
3
只需不调用fclose(),您就能获得最佳性能和可移植性。只需执行fflush(f),然后随意操作fd即可。 - Nate Eldredge
1
你是否在使用 FILE * 进行网络 IO?除非你为每个连接使用一个线程,否则阻塞 IO 会影响性能。而且 FILE * 不支持非阻塞 IO。 - HAL9000
显示剩余6条评论
2个回答

3
如果您想获得文件描述符并将其与FILE*分离,有一种支持的方法:
  1. 使用fileno()获取文件描述符。(POSIX)
  2. 使用dup()复制它。(POSIX)
  3. 使用fclose()正常关闭FILE。(c)
现在您只有一个文件描述符。

0

如果您真的想使用FILE对象而不是文件描述符,那么您不必担心close()关闭文件描述符: fclose()会为您完成这个操作。此外,如果性能很重要,您应该关注所有在f*()标准I/O函数中定义的fdopen()和包装系统调用。非常感谢所有评论!

另请参阅fclose man page

fclose()函数刷新由fp指向的流(使用fflush(3)写入任何缓冲输出数据)并关闭底层文件描述符


请注意,使用 fdopen() 中的文件描述符进行的任何 write 等系统调用都会被 fclose() 使无效。 - GooseDeveloper
我需要f*()函数进行缓冲,以减少系统调用。它不仅仅是一个包装器。 - Cosinus
@Cosinus 我明白了... 这个回答有帮助吗? - GooseDeveloper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接