同时写入两个流

时间:2009-06-25 13:01:54

标签: c linux io stream

有没有办法将两个流(或文件描述符)连接在一起,这样写入一个流也会写入第二个流? (C,Linux)

感谢。

5 个答案:

答案 0 :(得分:7)

使用funopenfwopen并提供您自己的写入多个FILE*的写入函数。

示例:

FILE *files[2] = ...;

FILE *f = fwopen((void *)files, my_writefn);

// ... use f as you like ...

int my_writefn(void *cookie, const char *data, int n) {
  FILE **files = (FILE **)cookie;
  fwrite(data, n, 1, files[0]);
  return fwrite(data, n, 1, files[1]);
}

(省略错误处理。)

请注意,funopenfwopen是BSD,而不是标准Linux。我不知道是否有与Linux兼容的等价物。

答案 1 :(得分:4)

我想到的第一件事也是“发球”。所以,让我们将C和shell与popen结合起来:

FILE * multi_out;

multi_out = popen( "tee file1.out > file2.out", "w");
/* error checks, actual work here */
pclose( multi_out);
/* error checks here */

作为一个Unix偏执狂,我假设你不是在Windows上尝试这个。

答案 2 :(得分:2)

不确定它是否是你想要的,但unix中的'tee'做了类似的事情。

答案 3 :(得分:2)

用户laalto是正确的,但在Linux上,您正在寻找的功能称为fopencookie。更正laalto的Linux示例导致:

int my_writefn(void *cookie, const char *data, int n) {
  FILE **files = (FILE **)cookie;
  fwrite(data, n, 1, files[0]);
  return fwrite(data, n, 1, files[1]);
}

int noop(void) { return 0; }
cookie_io_functions_t my_fns = {
  (void*) noop,
  (void*) my_writefn,
  (void*) noop,
  (void*) noop
};

FILE *files[2] = ...;

FILE *f = fopencookie((void *)files, "w", my_fns);

// ... use f as you like ...

当您写入f时,系统将执行您的my_writefn函数,并将传递给fwrite的数据传递给它。为了简化操作,您可能还希望将文件流的缓冲更改为面向行:

setvbuf(f, NULL, _IOLBF, 0);

这将缓冲传递给fwrite的数据,直到输出换行或从连接到进程的任何流(例如stdin)读取任何数据。 注意:您必须在sevbuf之后但在将任何数据写入流之前调用fopencookie

我使用行缓冲,因为我通常使用fopencookie将stderr重定向到syslog,或者通过网络套接字,并且处理面向行的数据更容易,更有效。

答案 4 :(得分:1)

您可以使用boost::iostreams实现类似于tee的功能。