在 JAVA 中使用运行时 class 时如何更改标准输入

How to change stdin when using Runtime class in JAVA

我想使用 tesseract 来识别一些文本,我将使用 Runtime class 来执行系统命令。在这里,我想使用 stdin 输入我的 img ,而不是读取文件。

    private String preprocessCmdCommand(BufferedImage img) throws IOException, InterruptedException {
        String cmd = "D:\Program Files\Tesseract-OCR\tesseract.exe stdin output -l chi_sm";
        Runtime run = Runtime.getRuntime();
        try {
            Process p = run.exec(cmd);
            // Write to the standard input stream
            OutputStream stdin = p.getOutputStream();
            stdin.write(HelpFunction.getImageBinary(img, "png")); //(TesseractOcr.java:40)
            InputStream stdout = p.getInputStream();
            consumeInputStream(stdout);

            if (p.waitFor() != 0) {
                if (p.exitValue() == 1)
                    System.err.println("fail!");
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

我尝试了第一个答案建议的方法,但出现异常。

java.io.IOException: pipe is closing
    at java.base/java.io.FileOutputStream.writeBytes(Native Method)
    at java.base/java.io.FileOutputStream.write(FileOutputStream.java:347)
    at java.base/java.io.BufferedOutputStream.write(BufferedOutputStream.java:123)
    at java.base/java.io.FilterOutputStream.write(FilterOutputStream.java:108)
    at ocr_processor.TesseractOcr.preprocessCmdCommand(TesseractOcr.java:40)
    at ocr_processor.TesseractOcr.recognizeSingleText(TesseractOcr.java:57)
    at Test.testOrientFunction(Test.java:32)
    at Test.main(Test.java:42)
[INFO ] 2020-07-16 08:57:42,783 method:Test.testOrientFunction(Test.java:32)

我的平台是windows10,JavaSDK是14.0.1.

启动进程时,Process.getOutputStream() 方法 returns 写入进程标准输入流的流。

Process p = ...
OutputStream stdin=p.getOutputStream();
// Write to the standard input stream
stdin.write(...);

ProcessBuilder class 为您提供更多控制:例如,您可以将标准输入连接到文件。

那么今天我从其他问题中得到了一个想法。我终于用下面的代码实现了我的目标!

        Runtime runtime = Runtime.getRuntime();
        try {
            Process process = runtime.exec("cmd /c tesseract stdin stdout");
            OutputStream os = process.getOutputStream();
            os.write(util.HelpFunction.getBinaryImage(img));
            os.close();
            consumeInputStream(process.getInputStream());
            int exitVal = process.exitValue();
            System.out.println("process exit value is " + exitVal);
        } catch (IOException e) {
            e.printStackTrace();
        }

谢谢你帮助我! :)