如何确定进程是否等待用户输入

huangapple go评论72阅读模式
英文:

How to determine if the process waits input from the user

问题

public void runFile(String input) {
    try {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("bash", "-c", "./a.out");
        Process process = processBuilder.start();

        BufferedOutputStream writer = new BufferedOutputStream(process.getOutputStream());
        BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        writer.write((input + "\n").getBytes());
        writer.flush();

        String s = null;
        // 从命令中读取输出:
        textArea2.setText(stdInput.readLine());
        while ((s = stdInput.readLine()) != null)
            textArea2.setText(textArea2.getText() + "\n" + s);

        // 读取尝试命令时出现的任何错误:
        if ((s = stdError.readLine()) != null) {
            textArea2.setText(s);
            while ((s = stdError.readLine()) != null) {
                textArea2.setText(textArea2.getText() + "\n" + s);
            }
        }

    } catch (Exception e) {
        textArea2.setText(e.toString());
        e.printStackTrace();
    }
}
英文:

My app is to take c++ CPP file and compile it and then run it. everything seems to be perfect. but when the user forgets to but the input and the c++ program require an input the program stops working. so is there is a way to know if the c++ program requires user input or not so I can handle the situation when the user forgets to but input? and if not how can I treat this situation?

my code for run function is:

public void runFile(String input) {
    try {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("bash", "-c", "./a.out");
        Process process = processBuilder.start();

        BufferedOutputStream writer = new BufferedOutputStream(process.getOutputStream());
        BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        writer.write((input + "\n").getBytes());
        writer.flush();

        String s = null;
        // Read the output from the command:
        textArea2.setText(stdInput.readLine());
        while ((s = stdInput.readLine()) != null)
            textArea2.setText(textArea2.getText() + "\n" + s);
        
        // Read any errors from the attempted command:
        if((s = stdError.readLine()) != null) {
            textArea2.setText(s);
            while ((s = stdError.readLine()) != null) {
                textArea2.setText(textArea2.getText() + "\n" + s);
            }
        }

    } catch (Exception e) {
        textArea2.setText(e.toString());
        e.printStackTrace();
    }
}

答案1

得分: 1

在大量的搜索和阅读关于这个错误的信息后,我发现没有办法知道进程在写输出之前是否等待输入,而且在 Process 中也没有办法阻止 Java 程序在 C++ 程序需要两个输入时冻结和停止工作,例如用户只输入了一个输入。

如何处理这种情况: 我使用了如下所示的新代码中的 Thread,以在出现这种情况并阻止 Java 程序冻结时保持其活动状态。

public byte runFile(String input, byte compilere, String fileName) {
    try {
        ProcessBuilder processBuilder = new ProcessBuilder();

        if (compilere == 0) // c++ 代码
            processBuilder.command("bash", "-c", "./a.out");
        else
            processBuilder.command("bash", "-c", "java " + fileName);

        Process process = processBuilder.start();

        BufferedOutputStream writer = new BufferedOutputStream(process.getOutputStream());
        BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        if (!input.isEmpty()) {
            writer.write((input + "\n").getBytes());
            writer.flush();
        } else {
            textArea2.setText("Input field is empty!");
            return 1;
        }

        // 从命令读取输出:
        thread1 = new Thread() {
            public void run() {
                try {
                    String s = null;
                    s = stdInput.readLine();
                    if (s != null) {
                        textArea2.setText(s);
                        while ((s = stdInput.readLine()) != null)
                            textArea2.setText(textArea2.getText() + "\n" + s);
                    }
                    thread2.start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        // 读取尝试命令中的任何错误:
        thread2 = new Thread() {
            public void run() {
                try {
                    String s = null;
                    s = stdError.readLine();
                    if (s != null) {
                        textArea2.setText(s);
                        while ((s = stdError.readLine()) != null)
                            textArea2.setText(textArea2.getText() + "\n" + s);
                    }

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

        thread1.start();

        thread3 = new Thread() {
            @Override
            public void run() {
                try {
                    sleep(8000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (textArea2.getText().isEmpty()) {
                    textArea2.setText("The input is not complete or your program is slow!");
                }
            }
        };
        thread3.start();

    } catch (Exception e) {
        textArea2.setText(textArea2.getText() + "\n" + e.toString());
        e.printStackTrace();
        return 1;
    }
    return 0;
}

编辑: 根据 Marquis of Lorne 的评论,我处理了没有输入但 C++ 应用程序需要输入的情况。

英文:

After a lot of searches and reading about this bug I found that there is no way to know if the process waits for input before writing output and also there is no way in Process class to stop the java program from being frozen and stopped working when the c++ program requires two inputs for example and the user entered only one input.

How to deal with this situation: I used Thread as shown in the new code below to keep the java program alive when this situation acquires and stops it from being frozen.

public byte runFile(String input, byte compilere, String fileName) {
try {
ProcessBuilder processBuilder = new ProcessBuilder();
if (compilere == 0) // c++  code
processBuilder.command("bash", "-c", "./a.out");
else
processBuilder.command("bash", "-c", "java " + fileName);
Process process = processBuilder.start();
BufferedOutputStream writer = new BufferedOutputStream(process.getOutputStream());
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
if (!input.isEmpty()) {
writer.write((input + "\n").getBytes());
writer.flush();
} else {
textArea2.setText("Input field is empty!");
return 1;
}
// Read the output from the command:
thread1 = new Thread() {
public void run() {
try {
String s = null;
s = stdInput.readLine();
if (s != null) {
textArea2.setText(s);
while ((s = stdInput.readLine()) != null)
textArea2.setText(textArea2.getText() + "\n" + s);
}
thread2.start();
} catch (Exception e) {
e.printStackTrace();
}
}
};
// Read any errors from the attempted command:
thread2 = new Thread() {
public void run() {
try {
String s = null;
s = stdError.readLine();
if (s != null) {
textArea2.setText(s);
while ((s = stdError.readLine()) != null)
textArea2.setText(textArea2.getText() + "\n" + s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread1.start();
thread3 = new Thread() {
@Override
public void run() {
try {
sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (textArea2.getText().isEmpty()) {
textArea2.setText("The input is not complete or the your program is slow !");
}
}
};
thread3.start();
} catch (Exception e) {
textArea2.setText(textArea2.getText() + "\n" + e.toString());
e.printStackTrace();
return 1;
}
return 0;
}

Edit: After Marquis of Lorne 's comment I handled the situation when there is no input and the c++ app requires an input.

huangapple
  • 本文由 发表于 2020年8月19日 00:26:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/63472833.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定