我将FM-SBLEX Saldo程序包装在Java库中。
Saldo是用Haskell编写的,并且在词典中查找stdin上给出的行,例如
echo "ord"|./sblex/bin/saldo dicts/saldo.dict
将以下内容输出到stdout
{"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。
在我的Java库中,我使用ProcessBuilder启动它,并设置一个线程将stdout和stderr转储到我的程序的stdout,另一个线程写一个单词和一个换行符,然后刷新outputStream
在控制台上,saldo每次按回车键都会返回结果,但在我的包装器中,只有在关闭outputStream后才会返回所有输入的结果(请参阅下一个代码块中注释掉.close())
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);
Writer的运行覆盖:
public void run() {
try {
outputStream.write("ord\n".getBytes());
outputStream.flush();
//outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
读取输入的Haskell代码
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
如果binPath =“cat”和dictPath =“ - ”我的java程序在每次刷新后输出输入。知道为什么这个haskell程序只关闭outputStream之后才处理输入?
注意:正如答案所示,不是hGetLine没有返回(正如我所假设的那样),而是缓存的输出,因为我正在使用的Haskell实现默认为阻塞缓冲区,如果它不是从控制台。
答案 0 :(得分:4)
您的Haskell程序可能正在缓冲其输出。 (当写入终端时进行行缓冲,写入其他任何内容时进行缓冲。)
尝试添加
hSetBuffering stdout LineBuffering
在计划开始附近。
More about buffering in Haskell.
(编辑回应Daniel Wagner的评论。)