Java简单的Haskell脚本

时间:2019-02-27 11:34:11

标签: java haskell

尝试通过使用Java代码在Haskell中运行简单的脚本。 (Windows 10)

haskell脚本如下:

import Data.Char(toUpper)
main = interact (map toUpper)

我用ghc制作了一个simple.exe文件,它可以从cmd模块按预期工作。我写了一个简单的字符串,并用大写字母答复了相同的字符串,我可以重复此操作,直到选择停止程序为止。

但是当我尝试通过Java运行该程序时,它将无法正常运行。我可以提供输入,但是为了获得输出,我需要关闭输入提要。

public class Main {
    public static void main(String[] args) {
        try {
            Process process = new ProcessBuilder("simple").start();

            InputStream processInputStream = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(processInputStream));
            OutputStream processOutputStream = process.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(processOutputStream));
            char[] bt = ("Hello").toCharArray();
            writer.write(bt);
            writer.flush();
            writer.newLine();
            processOutputStream.close(); -- Only works if I close output stream,.
            System.out.println(reader.readLine());


        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如何在不关闭Java程序中的输出提要的情况下获得输出。

重新启动该过程是可行的,但是执行时间太长了。

我尝试对程序进行线程化,结果相同。

2 个答案:

答案 0 :(得分:2)

BufferedWriter在执行newLine()时不会自动刷新其输出。因此,您的Haskell程序将不会收到换行符并永远等待。

调用close()时,所有剩余的缓冲输出都将被刷新(但是,当然,您不想这样做)。

因此解决方案应该是

writer.write(bt);
writer.newLine();
writer.flush();

您还可以使用PrintWriter,它具有自动换行刷新选项并且可以理解字符串(通过print方法),因此无需弄乱char[]

最后,如果您打算同时发送或发送大量文本,则当程序无法再发送输出时,由于接收Java代码,您可能必须调整缓冲区大小或使用多个线程来避免死锁。侧缓冲区已满,您目前尚未读出。有关解决方案,请参见此thread

答案 1 :(得分:1)

我做了一些实验,我需要在Haskell端进行行缓冲,否则输出不会及时刷新。

import Data.Char(toUpper)
import System.IO

main = do
  hSetBuffering stdout LineBuffering
  interact (map toUpper)

实际上,我发现从Java调用stdout时最初将其设置为BlockBuffering,这会缓冲太多。

请注意,正如Thilo所指出的,为了在Haskell端使用LineBuffering,必须先在Java端使用writer.newLine(),然后刷新(em ),否则大写输出将不会被刷新(在Haskell中)。