使用fdopen的正确方法 [英] Correct way of using fdopen

查看:124
本文介绍了使用fdopen的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的意思是将文件描述符与文件指针相关联,并使用其进行写入. 我在下面放了程序io.cc:

I mean to associate a file descriptor with a file pointer and use that for writing. I put together program io.cc below:

int main() {
    ssize_t nbytes;
    const int fd = 3;
    char c[100] = "Testing\n";
    nbytes = write(fd, (void *) c, strlen(c));     // Line #1
    FILE * fp = fdopen(fd, "a");
    fprintf(fp, "Writing to file descriptor %d\n", fd);
    cout << "Testing alternate writing to stdout and to another fd" << endl;
    fprintf(fp, "Writing again to file descriptor %d\n", fd);
    close(fd);     // Line #2
    return 0;
}

我可以交替注释第1行和/或第2行,编译/运行

I can alternately comment lines 1 and/or 2, compile/run

./io 3> io_redirect.txt

,然后检查io_redirect.txt的内容. 每当第1行未注释时,它就会在io_redirect.txt中产生预期的行Testing\n. 如果第2行有注释,我会得到预期的行

and check the contents of io_redirect.txt. Whenever line 1 is not commented, it produces in io_redirect.txt the expected line Testing\n. If line 2 is commented, I get the expected lines

Writing to file descriptor 3
Writing again to file descriptor 3

io_redirect.txt中的

. 但是,如果不加注释,则这些行不会显示在io_redirect.txt中.

in io_redirect.txt. But if it is not commented, those lines do not show up in io_redirect.txt.

  • 那是为什么?
  • 使用 fdopen 的正确方法是什么?

注意. 对于(a)="a href =" https://stackoverflow.com/questions/61852010/smart-write-to-arbitrary-file-descriptor-from-cc> Smart-从C/C ++写入任意文件描述符 我说部分"是因为我可以使用C风格的fprintf. 我仍然想也使用C ++风格的stream<<.

NOTE. This seems to be the right approach for a (partial) answer to Smart-write to arbitrary file descriptor from C/C++ I say "partial" since I would be able to use C-style fprintf. I still would like to also use C++-style stream<<.

编辑: 我忘记了fclose(fp). 那关闭"了问题的一部分.

EDIT: I was forgetting about fclose(fp). That "closes" part of the question.

推荐答案

那是为什么?

Why is that?

打开的流("stream"是打开的FILE*)被块缓冲,因此在刷新文件之前,不会将任何内容写入目标.从应用程序退出关闭所有打开的流刷新流.

The opened stream ("stream" is an opened FILE*) is block buffered, so nothing gets written to the destination before the file is flushed. Exiting from an application closes all open streams, which flushes the stream.

因为在刷新流之前关闭了基础文件描述符,所以程序的行为是不确定的.我真的建议您阅读 posix 2.5.1文件描述符与标准I/O流(尽管如此,它还是用可怕的语言编写的),

Because you close the underlying file descriptor before flushing the stream, the behavior of your program is undefined. I would really recommend you to read posix 2.5.1 Interaction of File Descriptors and Standard I/O Streams (which is written in a horrible language, nonetheless), from which:

...如果使用了两个或多个句柄,并且其中任何一个是流,则应用程序应确保按以下所述协调它们的动作.如果不这样做,则结果是不确定的.

... if two or more handles are used, and any one of them is a stream, the application shall ensure that their actions are coordinated as described below. If this is not done, the result is undefined.

...

对于第一个手柄,适用以下第一个适用条件. ...

For the first handle, the first applicable condition below applies. ...

  • ...

  • ...

如果它是一个开放的用于写入或追加的流(但也不开放用于读取),则应用程序应执行fflush()或将其关闭.

If it is a stream which is open for writing or appending (but not also open for reading), the application shall either perform an fflush(), or the stream shall be closed.

句柄"是文件描述符或流. 活动手柄"是您执行操作的最后一个手柄.

A "handle" is a file descriptor or a stream. An "active handle" is the last handle that you did something with.

fp流是打开的活动句柄,可以附加到文件描述符3.因为fp是活动句柄并且不会被刷新,并且使用close(fd)将活动句柄切换到fd,所以程序的行为是不确定的.

The fp stream is the active handle that is open for appending to file descriptor 3. Because fp is an active handle and is not flushed and you switch the active handle to fd with close(fd), the behavior of your program is undefined.

我的猜测是,最有可能发生的情况是,由于fd已关闭,您的C标准库实现在main返回后调用了fflush(fp),因此某些内部write(3, ...)调用返回了错误,并且没有任何内容写入输出.

What is my guess and most probably happens is that your C standard library implementation calls fflush(fp) after main returns, because fd is closed, some internal write(3, ...) call returns an error and nothing is written to the output.

使用fdopen的正确方法是什么?

What is the correct way of using fdopen?

您介绍的用法是使用fdopen的正确方法.

The usage you presented is the correct way of using fdopen.

这篇关于使用fdopen的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆