2009-06-25 7 views
5

2つのストリーム(またはファイルディスクリプタ)を結合して、1つのストリームへの書き込みも2つ目のストリームへの書き込みを行う方法はありますか? (C、Linux)2つのストリームに同時に書き込み

ありがとう。

答えて

1

Linuxでは、探している機能はfopencookieとなります。あなたはfに書き込むとき

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 ... 

は、システムはそれをfwriteに渡されたデータを渡すあなたのmy_writefn機能を実行します:Linux用の修正laaltoの例では、その結果。物事を簡単にするために、あなたはまた、行指向するためにあなたのファイルストリームのバッファリングを変更することがあります。改行までfwriteに渡されたデータをバッファリングする

setvbuf(f, NULL, _IOLBF, 0); 

が出力されているか、どのデータがどのから読み込まれますプロセスに接続されたストリーム(stdinなど)。 注: fopencookieの後で、データがストリームに書き込まれる前に sevbufに電話する必要があります。

私は通常、stderrをsyslogまたはネットワークソケット経由でリダイレクトするためにfopencookieを使用し、行指向のデータを処理する方が簡単で効率的であるため、回線バッファリングを使用します。

1

teeの機能に類似したものを実装できます。

+0

Cの例がありますか?それは厳密にC++だから) – Skurmedel

+0

ごめんなさい。 – stefanB

2

あなたが望むものであるかどうかは不明ですが、UNIXでは「tee」と似ています。

+0

"C++"の人は改造されましたが、 "他の人の仕事を踏まえて"提案するために改造されました。それは正しくない... – Roboprog

4

私に気づいた最初のものは「ティー」でした。それでは、popenのでCシェルを組み合わせてみましょう:

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上でこれをしようとしていないと想定しています。

+0

ああ、あなたは "Linux"と言った。グッドボーイ:-) – Roboprog

+0

この方法でも、2つ以上のファイルに書き込むことができます。ちょっとしたティーン使いの問題。 ref。 http://www.linuxandlife.com/2013/05/how-to-use-tee-command.html – JagsVG

6

funopenまたはfwopenを使用し、複数の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は、標準のLinuxでBSDとされないこと。 Linuxと互換性があるかどうかはわかりません。

+0

明らかに、いいえ。それらはマニュアルページにはありません(私のシステムでは少なくとも)。 – jackhab

+0

funopenはBSDとMac OS X上にあります。Linuxではfopencookieを使用します。 – mark4o

+0

@ mark4o:情報ありがとうございます。 @ジャック:fopencookie()を使った実装はかなり似ているようです。ここで私の答えを更新していないが、先を進むためのいくつかの指針が必要です。 – laalto