【发布时间】:2010-11-05 20:07:35
【问题描述】:
有没有办法将两个流(或文件描述符)耦合在一起,以便写入一个流也会写入第二个流? (C,Linux)
谢谢。
【问题讨论】:
有没有办法将两个流(或文件描述符)耦合在一起,以便写入一个流也会写入第二个流? (C,Linux)
谢谢。
【问题讨论】:
使用funopen 或fwopen 并提供您自己的写入函数来写入多个FILE*s。
例子:
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]);
}
(省略错误处理。)
请注意,funopen 和 fwopen 是 BSD,而不是标准 Linux。我不知道是否有与 Linux 兼容的等价物。
【讨论】:
我首先想到的也是“tee”。所以,让我们将 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 上尝试这个。
【讨论】:
用户 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 的数据,直到输出换行符或从附加到进程的任何流(例如标准输入)中读取任何数据。 注意:您必须在fopencookie 之后但在任何数据写入流之前调用sevbuf。
我使用行缓冲,因为我通常使用fopencookie 将 stderr 重定向到 syslog 或通过网络套接字,并且处理面向行的数据更容易和更有效。
【讨论】:
不确定是不是你想要的,但 unix 中的 'tee' 有类似的功能。
【讨论】:
您可以使用boost::iostreams 实现类似于tee 的功能。
【讨论】: