0

標準入力へのリダイレクトを使用して、名前付きパイプを介して断続的に送信されるデータを読み取ることは可能ですか?

私がやりたいことはこれです:

$ mkfifo pipe
$ ./test < pipe

別の端末で:

$ cat datafile > pipe
$ cat datafile > pipe

パイプへの情報のダンプを繰り返します。これは初回のみ有効です。

動作を示すテスト用のデモ プログラムを次に示します。

int main(int argc, char *argv[]) {  
    char input_string[30];
    while(1) {
        while( cin.read(input_string, 30) || cin.gcount()!=0 ) {
            cout << "!" << endl;
        }
    }
return 1;
}

どうしたの?リダイレクトは、パイプへの単一の送信のコンテンツのみを提供しますか? パイプの名前をパラメーターとして受け取り、この方法で書き込むために開いたままにする実際の製品コードのバージョンを既に作成しました。おそらくそれが答えです。しかし、リダイレクトでこれを行う方法があるかどうか疑問に思っています。

4

2 に答える 2

1

次のようにパイプからの入力をリダイレクトすると:

./test < pipe

シェルは読み取り用にパイプを開き、プログラムを開始します。open(2)ただし、パイプを開くことは、ライター (ブロック) が存在するまで完了しません。別のプロセスが書き込み用にパイプを開くと、元のopen呼び出しが完了し、2 つのプロセスが通信できるようになります。ライターがパイプの終わりを閉じると、読み取り側も閉じます。リーダーは EOF を取得します。

そのサイクルが完了したら、読み取り用にパイプを再度開いて別のサイクルを開始できますが、それは自分で行う必要があります。そのため、標準入力を読んでいる場合は、プログラムを再起動する必要があります。または、別のファイル記述子でパイプを再度開くこともできます。たとえば、次のようになります。

// Error checking omitted for expository purposes
int main(int argc, char **argv)
{
    while(1)
    {
        int fd = open("pipe", O_RDONLY);
        char buffer[30];
        int n;
        while((n = read(fd, buffer, sizeof(buffer)) > 0)
        {
            // Process input
        }
        close(fd);
    }

    return 0;
}

生の I/O を stdio でラップしたい場合は、;FILE*を使用できます。fdopen(3)ファイル記述子を C++ ストリーム オブジェクトでラップする方法は知りませんが、可能かもしれません。

于 2012-06-21T21:10:06.583 に答える
0
$ cat datafile > pipe

datafile の内容をパイプに送信し、EOF (ファイルの終わり) を送信します。この時点でリダイレクトは閉じられ、その後パイプにプッシュされたデータはリダイレクトされ./testなくなります。

于 2012-06-21T19:27:48.497 に答える