关于mode参数先搁置会儿,目前我们知道的是,使用fileno和fdopen进行转换,都是在原有的fd上进行操作,并未产生新的fd。那么,再次审视刚才的代码,是否发现了问题?
我们来检查下close(fd)的返回值,把close(fd)改成下列代码
if (-1 == close(fd)) {
perror("close");
exit(1);
}
$ gcc test.c $ ./a.out close: Bad file descriptor
没错,fclose在关闭文件指针的时候,内部其实也关闭了文件描述符(否则资源就泄露了),既然这里fp内部的文件描述符和fd是同一个,当fp被关闭时,fd也被关闭了,再次关闭fd就会出现“损坏的文件描述符”错误。
OK,现在回顾下fopen的第2个参数,又r/r+/w/w+/a/a+一共6种设置(windows平台的rb/rb+/wb/wb+暂且不谈),对比Linux手册我将对应的open设置列出来

依然是进行测试,修改fd_mode和fp_mode,看看实验结果
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
const int security = S_IRUSR | S_IWUSR;
const int fd_mode = O_RDWR | O_CREAT | O_TRUNC;
const char* fp_mode = "r";
int main()
{
int fd = open("new.txt", fd_mode, security);
FILE* fp = fdopen(fd, fp_mode);
if (fp == NULL) {
perror("fdopen");
exit(1);
}
close(fd);
return 0;
}
在fd_mode等价于"w+"时,fp_mode的6种设置(r/r+/w/w+/a/a+)均返回非空指针。
在fd_mode等价于"w"时,fp_mode6种设置只有"a"和"w"返回非空指针。
继续尝试"r"/"r+"/"a"/"a+"的设置,可以发现所谓“兼容”只与读写权限有关,O_RDWR兼容O_RDONLY和O_WRONLY,而后两者则只与自身兼容。
有意思的是O_APPEND(在末尾添加)和O_TRUNC(截断文件从头添加)也兼容。
The file position indicator of the new stream is set to that
belonging to fd, and the error and end-of-file indicators are cleared. Modes "w" or "w+" do
not cause truncation of the file. The file descriptor is not dup'ed, and will be closed when
the stream created by fdopen() is closed.
继续查看fdopen的手册内容,可以看到"w"和"w+"在这里不会导致文件截断。
后一句也印证了我们前面的实验结果:文件描述符不会被复制,文件指针被关闭时文件描述符也会被关闭。
PS:其实fdopen的手册上还有最后一句:The result of applying fdopen() to a shared memory object is undefined.
将fdopen用于共享内存对象的结果是未定义的。
总结
以上就是本文关于Linux中文件描述符fd与文件指针FILE*互相转换实例解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!








