私はFM-SBLEX SaldoプログラムをJavaライブラリにラッピングしています。Java ProcessBuilderを使用してhaskellを実行する:hGetLineはなぜoutputStreamを閉じると返されますか?
SaldoはHaskellで書かれており、stdinに与えられた行のレキシコンでルックアップします。
echo "ord"|./sblex/bin/saldo dicts/saldo.dict
プリント
{"ord":{"s_1":{"word":"ord","head":"sanna mina ord","pos":"abm","param":"invar 1:3-3","inhs":[],"id":"sanna_mina_ord..abm.1","p":"abm_i_till_exempel","attr":"3"},...
私は
./sblex/bin/saldo dicts/saldo.dict
でそれを実行した場合、私はEOFを送信するまで、それは私が、コンソールで入力した各行のルックアップを行うにstdoutに以下のようなものを。私のJavaライブラリで
、私はProcessBuilderをとそれを開始し、私のプログラムの標準出力をstdoutとstderrをダンプするためのスレッドを設定し、別のスレッドが単語と改行を書き込み、その後、コンソールで
をOutputStreamのフラッシュsaldoは結果に私がリターンを押すたびに返しますが、私のラッパーで、それは私が(次のコードブロックではコメントアウトされている。.closeを(参照))のOutputStream閉じるだけ一度私のすべての入力
ProcessBuilder pb = new ProcessBuilder(binPath, dictPath);
pb.redirectErrorStream(true);
saldoProcess = pb.start();
new Thread(new Reader(saldoProcess.getInputStream())).start();
new Thread(new Writer(saldoProcess.getOutputStream())).start();
saldoProcess.waitFor();
System.out.println("saldo exited.");
Thread.sleep(2000);
ライターの実行の結果を返します。上書き:
public void run() {
try {
outputStream.write("ord\n".getBytes());
outputStream.flush();
//outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
BINPATH = "猫" とDICTPATH =が場合は入力
run' :: Language a => a -> (String -> [Tok]) -> (String -> [[String]]) -> AnaType -> Stats -> IO Stats
run' l tokenizer f a st =
do b <- hIsEOF stdin
if b then return st
else do
s <- hGetLine stdin
analyze l a f (tokenizer s) st >>= run' l tokenizer f a
を読み込みHaskellコード " - " 私のJavaプログラムは、各フラッシュの後に入力して出力します。私はoutputStreamを閉じた後、このhaskellプログラムが入力を扱うのはなぜですか?
NB:答えとして、返されなかったhGetLine(私が想定したように)ではなく、Haskell実装のためにバッファリングされた出力です。コンソール。
入力の1行が出力の少なくとも一つの行に対応している場合、 'LineBuffering'はおそらくより適切です。 –
コード内で修正することはできますが、サードパーティのコードを変更する代わりに、コンソールからプログラムが実行されていると思うようにする方法を知っていますか?誰かが 'script/dev/null'の下で実行することを勧めているのを見たことがありますが、Javaがプラットフォームに依存しないこれを行う方法をサポートしているのだろうか? – jbothma
Javaのやり方についてはわかりませんが、Linux/OSX /その他のUnix上で実行していて、 'script'プログラムがインストールされていれば、Javaに' script -c 'を実行させることができます。 './sblex/bin/saldo dicts/saldo.dict'の代わりに/ sblex/bin/saldo dicts/saldo.dict"/dev/null'を実行してください。 – dave4420