带有 .exe 的 Java 输入/输出流

发布于 2024-10-21 04:33:04 字数 1918 浏览 6 评论 0原文

我想做的是,用Java启动一个.exe控制台程序,并使用Java从控制台窗口操作输入和输出流。我知道我可以从应用程序获取输入和输出流,这就是我目前正在做的事情:

    try {
        process = Runtime.getRuntime().exec("C:\\Users\\Owner\\Documents\\testApp\\console.exe");
    } catch (IOException e1) {
        e1.printStackTrace();
        return;
    }

    stdin = process.getOutputStream();
    stdout = process.getInputStream();

然后,我可以使用 BufferedReader 来显示 .exe 通常显示的输出,但是我不知道如何传递从 Java 应用程序控制台程序输入到实际的 .exe 输入流。我需要一些关于如何执行此操作的帮助。

编辑: 好的,我现在有了这个,它可以同时工作;但是,我似乎无法获得与从 Java 控制台窗口获取的任何输入相关的任何输出。

    new Thread(new Runnable() {
        public void run() {
            String line;
            BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
            try {
                while ((line = br.readLine()) != null) {
                    System.out.println("[OUT] " + line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {
        public void run() {
            try {
                byte[] buffer = new byte[1024];

                int bytesRead;
                while ((bytesRead = System.in.read(buffer)) != -1) {
                    for(int i = 0; i < buffer.length; i++) {
                        int intValue = new Byte(buffer[i]).intValue();
                        if (intValue == 0) {
                            bytesRead = i;
                            break;
                        }
                    }
                    // for some reason there are 2 extra bytes on the end
                    stdin.write(buffer, 0, bytesRead-2);
                    System.out.println("[IN] " + new String(buffer, 0, bytesRead-2) + " [/IN]");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

What I want to do is, launch a .exe console program with Java, and use Java to manipulate the input and output streams from the console window. I know I can get the input and output streams from an application, and this is how I am currently doing it:

    try {
        process = Runtime.getRuntime().exec("C:\\Users\\Owner\\Documents\\testApp\\console.exe");
    } catch (IOException e1) {
        e1.printStackTrace();
        return;
    }

    stdin = process.getOutputStream();
    stdout = process.getInputStream();

Then, I can use a BufferedReader to show output that the .exe would normally display, however I cannot figure out how to pass input from the Java application console program to the actual .exe input stream. I need some help with how to do this.

Edit:
Ok, I now have this, which works concurrently; however, I can't seem to get any output related to any input I take from the Java console window.

    new Thread(new Runnable() {
        public void run() {
            String line;
            BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
            try {
                while ((line = br.readLine()) != null) {
                    System.out.println("[OUT] " + line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {
        public void run() {
            try {
                byte[] buffer = new byte[1024];

                int bytesRead;
                while ((bytesRead = System.in.read(buffer)) != -1) {
                    for(int i = 0; i < buffer.length; i++) {
                        int intValue = new Byte(buffer[i]).intValue();
                        if (intValue == 0) {
                            bytesRead = i;
                            break;
                        }
                    }
                    // for some reason there are 2 extra bytes on the end
                    stdin.write(buffer, 0, bytesRead-2);
                    System.out.println("[IN] " + new String(buffer, 0, bytesRead-2) + " [/IN]");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

后知后觉 2024-10-28 04:33:04

您可以创建另一个不断从 Java 控制台读取数据的线程,将其重新写入进程的标准输入:

new Thread(
    new Runnable() {
      public void run() {
        try {
          byte[] buffer = new byte[1024];

          int bytesRead;
          while ((bytesRead = System.in.read(buffer)) != -1) {
            process.getOutputStream().write(buffer, 0, bytesRead);
          }
        } catch (IOException e) {
          // Do something with the error...
        }
      }
    }
  ).start();

You can create another thread that constantly reads from Java's console, re-writing it to the process's standard input:

new Thread(
    new Runnable() {
      public void run() {
        try {
          byte[] buffer = new byte[1024];

          int bytesRead;
          while ((bytesRead = System.in.read(buffer)) != -1) {
            process.getOutputStream().write(buffer, 0, bytesRead);
          }
        } catch (IOException e) {
          // Do something with the error...
        }
      }
    }
  ).start();
情绪失控 2024-10-28 04:33:04

首先,您需要同时使用 stdout/stderr (通过单独的线程)。否则,您可以阻止生成的进程,因为您没有消耗其输出。有关更多详细信息,请参阅此答案

要写入进程,我将用 BufferedWriter 包装 stdin OutputStream,然后简单地从 System.in< 写入该进程。 /代码>

Firstly, you need to be consuming stdout/stderr concurrently (via separate threads). Otherwise you can block your spawned process since you're not consuming its output. See this answer for more details.

To write to the process, I would wrap the stdin OutputStream with a BufferedWriter, and simply write to that from System.in

雨的味道风的声音 2024-10-28 04:33:04

使用 ProcessBuilder API。它有非常方便的选项来连接 stderr 和 stdout 流,因此您不必使用多个线程从流中读取数据。

redirectErrorStream(true) 

是你的朋友吗?

如果要向进程传递数据:

proc.getOutputStream().write(allmydata);

要读取数据:

proc.getInputStream().read(byteBuffer);

请注意以下事项: 如果输入数据超出了进程可以缓冲的范围,并且如果进程已经填满了其输出缓冲区,并且您不从输出缓冲区,您将遇到典型的死锁情况。在这种情况下,您要么必须在单独的进程中读取进程的输出并自己缓冲它,要么让进程首先将数据重定向到临时文件,然后在第二步中读取它。第一个变体的性能更高,但第二个变体更容易理解,如果有大量数据并且性能不重要,也可能是一个有效的选择。

Use the ProcessBuilder API. It has the very convenient option to join stderr and stdout streams, so you don't have to use multiple threads to read from the streams.

redirectErrorStream(true) 

is your friend here.

If you want to pass data to the process:

proc.getOutputStream().write(allmydata);

To read data:

proc.getInputStream().read(byteBuffer);

Please be aware of the following: If the input data is more than the process can buffer, and if the process already filled its output buffer, and you do not read from the output buffer, you will have a classic deadlock situation. In this case you either have to read output of the process in a separate process and buffer it yourself, or you make the process redirecting the data to a temporary file first, and read this in in a second step. The first variant is more performant, but the second is more easy to understand and might also be a valid option if there is much of data and performance doesn't count.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文