简体   繁体   English

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

[英]How to change stdin when using Runtime class in JAVA

I want to use tesseract to recognize some text and I will use Runtime class to exec system command.我想使用 tesseract 来识别一些文本,我将使用Runtime class 来执行系统命令。 Here, I want to use stdin to input my img,rather than reading a file.在这里,我想使用 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;
    }

I tried the method suggested by the first answer, but I got an exception.我尝试了第一个答案建议的方法,但出现异常。

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)

My platform is windows 10, Java SDK is 14.0.1.我的平台是windows 10,Java SDK是14.0.1。

When you start a process, the Process.getOutputStream() method returns a stream that writes to the standard input stream of the process.当您启动一个进程时, Process.getOutputStream()方法返回一个 stream 写入进程的标准输入 stream。

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

The ProcessBuilder class gives you more control: you can connect the stdin to a file for example. ProcessBuilder class 为您提供更多控制:例如,您可以将标准输入连接到文件。

I want to use tesseract to recognize some text and I will use Runtime class to exec system command.我想使用 tesseract 来识别一些文本,我将使用Runtime class 来执行系统命令。 Here, I want to use stdin to input my img,rather than reading a file.在这里,我想使用标准输入来输入我的 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;
    }

I tried the method suggested by the first answer, but I got an exception.我尝试了第一个答案建议的方法,但出现异常。

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)

My platform is windows 10, Java SDK is 14.0.1.我的平台是 windows 10,Java SDK 是 14.0.1。

Well today I get an idea from other questions.那么今天我从其他问题中得到了一个想法。 I finally use the following code to achieve my target!我终于用下面的代码达到了我的目的!

        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();
        }

Thanks for helping me: :)谢谢你帮助我: :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM