我的意思是将文件描述符与文件指针相关联,并将其用于写入。 我将程序io.cc
放在一起:
int main() {
ssize_t nbytes;
const int fd = 3;
char c[100] = "Testingn";
nbytes = write(fd, (void *) c, strlen(c)); // Line #1
FILE * fp = fdopen(fd, "a");
fprintf(fp, "Writing to file descriptor %dn", fd);
cout << "Testing alternate writing to stdout and to another fd" << endl;
fprintf(fp, "Writing again to file descriptor %dn", fd);
close(fd); // Line #2
return 0;
}
我可以交替注释第 1 行和/或第 2 行,编译/运行
./io 3> io_redirect.txt
并检查io_redirect.txt
的内容。 每当第 1 行未被注释时,它就会io_redirect.txt
生成预期的行Testingn
。 如果注释了第 2 行,我得到预期的行
Writing to file descriptor 3
Writing again to file descriptor 3
在io_redirect.txt
. 但是,如果不对其进行注释,则这些行不会出现在io_redirect.txt
中。
- 为什么?
- 使用
fdopen
的正确方法是什么?
注意。 这似乎是从 C/C++ 对任意文件描述符进行智能写入的(部分(答案的正确方法 我说"部分",因为我可以使用 C 样式fprintf
. 我仍然想也使用C++式stream<<
.
编辑: 我忘记了fclose(fp)
. 这"结束"了问题的部分。
为什么呢?
打开的流("流"是打开的FILE*
(是块缓冲的,因此在刷新文件之前不会将任何内容写入目标。从应用程序退出将关闭所有打开的流,这会刷新流。
由于在刷新流之前关闭基础文件描述符,因此程序的行为是未定义的。我真的建议您阅读posix 2.5.1文件描述符和标准I/O流的交互(尽管如此,它是用可怕的语言编写的(,其中:
。如果使用两个或多个句柄,并且其中任何一个是流,则应用程序应确保按如下所述协调其操作。如果不这样做,则结果是不确定的。
。
对于第一个句柄,以下第一个适用条件适用。
。
如果它是打开用于写入或追加(但未打开以供读取(的流,则应用程序应执行 fflush((,或者应关闭流。
"句柄"是文件描述符或流。"活动句柄"是执行某些操作的最后一个句柄。
fp
流是打开以追加到文件描述符3
的活动句柄。由于fp
是活动句柄并且未刷新,并且您将活动句柄切换到fd
close(fd)
,因此程序的行为是未定义的。
我的猜测和最有可能发生的是,您的 C 标准库实现在main
返回后调用fflush(fp)
,因为fd
关闭,一些内部write(3, ...)
调用返回错误,并且没有写入输出。
使用fdopen的正确方法是什么?
您提供的用法是使用fdopen
的正确方法。