2012-09-21 10 views
9

バッファなしのサブプロセスからの出力を簡単に読み取る方法はありますか?私はJavaからCプログラムを呼び出そうとしていますが、明らかに、パイプに接続されているときはstdoutブロックバッファであり、コンソールに接続されているときにはラインバッファされています。私はCプログラムを変更することはできません。ウィンドウ上のバッファなしサブプロセスstdout

多分、プログラムがコンソールに接続されていると思ってしまうのを欺く方法がありますか? Linux上でも動作するソリューションのボーナスポイント。

+1

同じマシンにsshを開き、そのように実行できます。私はこれを行うには何も簡単ではないと思う。 –

+0

OSレベルで「回線バッファリング」が発生します。例えば、Linuxでは、 "ioctl()"を使って端末を "rawモード"に設定します。おそらく、 "Java端末I/O"、 "Java curses"などのキーワードのGoogleを使用できますか? – paulsm4

+0

私はすでにインターネットとSOで徹底的に検索しました。これは一般的な問題ですが、私はWindowsのための単一の解決策を見つけませんでした –

答えて

-1

OK -

1)は、「ライン入力をバッファリング」元のUnixおよびシリアル・モードVTxx端末にさかのぼる、コンソールモードのプログラムのための共通のイディオムです。

2) "生のバッファされていない" I/O(一度に1行ではなく一度にキーストローク)を読むことができますが、詳細はOS固有のものです。あなたが何であれは、特定のOSで行うにはが必要です。ほとんどの場合、確かにからです。

3)Windowsのキーボード上で、「矢印キー」または「ページダウン」キーを傍受できるように思えます。おそらく、ゲームをプレイしたり、コンソールモードのユーザーインターフェイスと対話したりするためのものです。

4)いくつかのオプションがあります。それが十分でない場合は、正確にどのようにあなたがあなたのJavaを取得しようとしているの詳細を記入してください

:あなたが考慮したいかもしれません一つは、テストのために使用される「ロボット」APIであり、プログラムをCプログラムとやりとりする(そして、プラットフォームが実際にはWindowsであるかDOSプロンプトであるかを明確にする)。

+0

私は生の入力を必要としません、ラインバッファで十分です。 Cプログラムを実行するために 'Runtime.getRuntime()。exec(command);'または 'new ProcessBuilder(command).start();'を試してから 'process.getInputStream()'を実行しましたが、バッファリングされたストリーム。 –

-1

あなたは

org.apache.commons.io.input.Tailer 
+0

残念ながら、ファイルへの書き込みはほぼ確実にバッファリングされます。 –

+0

以下のコメントのユーザーは、回線のバッファリングは問題ないと言います。実行可能ファイルから出力を直接リダイレクトしたいのですが、javaからではなく、おそらく動作します。 – user1569047

+0

私はWindowsでラインバッファリングを行うことについて聞いたことがありません。典型的には、出力はブロック・バッファまたは非バッファのいずれかです。いずれにしても、パイプへのリダイレクトがブロックバッファリングされている場合、ファイルへのリダイレクトはほぼ確実にブロックされます。これはJavaの問題ではなく、サブプロセス内のCランタイムライブラリの動作と関係しています。 –

0

を使用してJavaで別のスレッドからのファイルには、= 0、環境変数BUF_1_を使用してみましたファイルにC出力をリダイレクトして、尾だろうか?それを行うには

+0

私はGoogle検索からわかる限り、これはglibcライブラリのバッファリングを抑制するメカニズムを提案していましたが、開発者はそれを拒否しました。あなたはより良いリファレンスを持っていますか? (私はVisual Studioで試してみましたが、動作していないようです) –

-1

最良の方法は、私はどうなるのか、出力

を読むためにスレッドを使用している:私は、プロセス(process.getInputStream(からの入力を与える場所を呼び出し可能(Runnableをも動作します)を使用して、 ))と出力を格納したい出力を指定します。 StdErrについても同じことを行う必要があります。結果の出力は、好きなものを使って読み込むことができます。

public Object call() throws IOException { 
     int bytesRead; 
     byte[] b = new byte [ this.maxBlockSize ]; 

     try { 
      while ((bytesRead = this.input.read (b)) != -1) { 
       this.output.write (b, 0, bytesRead); 
      } 
     } finally { 
      if (this.output != null) { 
       this.output.close(); 
      } 
     } 
     return null; 
    } 
+0

これはOPの問題を解決していません。出力は、親プロセスではなく、子プロセスでバッファされています。 –

+0

このようにした場合、別のスレッドで読み込まれているためブロックされているかどうかは関係ありません。 – azl

+2

あなたは、子プロセスの出力を直ちに必要とするという点を見逃しています。子供のstdoutバッファが最終的にいっぱいになる未確定の将来の時間ではありません。読み込みを非ブロックにすることは、子プロセスを待っている間に彼のプログラムが他の仕事をする可能性があることを意味しますが、出力を速くするのには役立ちません。 (特に、子プロセスが入力を待っているが、送信する入力を知る前に親プロセスが出力を見る必要があるため、プロセスはデッドロックします。) –

1

それは素晴らしい解決策ではないのですが、あなたは絶望している場合、十分なあなたはcom0comまたはその誘導体のようなヌルモデムエミュレータを使用できるように、ランタイムライブラリは、おそらくシリアルポートをバッファリングしません。

関連する問題