【问题标题】:redirect pipe's read end to a file descriptor将管道的读取端重定向到文件描述符
【发布时间】:2019-04-05 15:56:20
【问题描述】:

我有两个子进程,它们共享父进程的公共管道描述符。关闭端等没有问题。问题是我希望将管道的读取端重定向到文件描述符,而不是保存缓冲区并将缓冲区的内容写入文件。是否可以?我的代码 sn-p 如下

// we're sure we can read from fd[0], I did it sucessfully
// I mean there is no problem about the communication

int open_fd = open(filename, O_WRONLY|O_CREAT, 0666);
if (dup2(open_fd,fd[0]) == -1) {
    perror("error ");
    return 1;
}
if (close(open_fd) == -1) {
    perror("close error");
    return 1;
}

当我执行上述代码时,我没有写入名为filename 的文件。顺便问一下,有没有必要通过调用close(open_fd)来关闭open_fd?由于dup2 已经关闭它。

【问题讨论】:

  • 通常情况下,您会使用dup2(a,b); close(a)。做dup2(a,b); close(b) 真的没有任何意义。
  • @WilliamPursell 谢谢先生,我编辑了它。那么,现在的问题是什么?我该怎么办?
  • 您不能通过复制文件描述符来神奇地将管道更改为文件。
  • @IanAbbott 那么我应该分别持有一个缓冲区、读入缓冲区、打开文件进行写入和写入文件吗?或者我该怎么办?
  • @concurrencyboy 这取决于。为什么首先需要创建管道?

标签: c pipe io-redirection dup2


【解决方案1】:

您可能误解了dup2 的用途。它只是改变了文件描述符的“含义”,因此它现在“指向”与另一个描述符相同的流。但它不会以任何方式将数据从一个文件描述符传输到另一个文件描述符。要真正实现你想要的,你可以试试splice:

int open_fd = open(filename, O_WRONLY|O_CREAT, 0666);
splice(fd[0], NULL, open_fd, NULL, size, 0);

请注意,您必须指定要传输的数据量(上例中的size 变量)。

【讨论】:

  • 巧妙地使用splice,虽然它是Linux特有的。
【解决方案2】:

当我执行上述代码时,我没有写入名为 filename 的文件。

当然不是。当您调用dup2(open_fd,fd[0]) 时,您使存储在fd[0] 中的整数值引用open_fd 所做的同一文件,但这与馈送到管道写入端的字节发生的情况没有直接关系.它只是间接影响它们,通过导致其值最初存储在fd[0] 中的文件描述符编号在打开时首先被关闭。

文件描述符基本上是将整数映射到内核中打开文件描述的表的键。 dup2() 更改目标 FD 映射到的打开文件描述;它不会修改打开的文件描述本身或影响其语义,它位于管道所在的那个级别。

写入管道写入端的字节是通过读取管道从管道的读取端获得的。不管你怎么做,它们最初都驻留在内存和/或 CPU 寄存器中。要使它们从那里转到文件,您需要将它们发送到那里。例如,您可能会设置一个线程,其目的是读取管道中可用的任何字节,然后将它们写入您的文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 2011-07-03
    相关资源
    最近更新 更多