以 ProcessBuilder 开始的进程停止提供数据
Process started with ProcessBuilder stop supplying data
我需要 运行 来自 java 运行ning 的 unix 程序 windows。 unix 程序将文件名作为第一个参数,处理该文件,并且 returns stdout 上的处理文件。
以下命令在 CMD 控制台中完美运行:
wsl.exe /home/user/process /mnt/c/Users/user/input
它将标准输出和标准错误打印到控制台;或者我可以将 stdout 重定向到一个新文件,该文件的重量为 1.2MB。
我想从 Java 做同样的事情。下面的代码是最简化的版本
ProcessBuilder toCsv = new ProcessBuilder("wsl.exe", "/home/user/process", "/mnt/c/Users/user/input");
Process proc = toCsv.start();
try (InputStream is = proc.getInputStream()){
for(int i=0; is.read() != -1; i++) {
System.out.println(i);
}
}
这总是在字节号 380927 上停止。调试器显示它在 FileInputStream.read
上停止
- 我试过使用重定向将标准输出发送到文件
- 我试过只读取 stderr
- 我尝试在
waitFor
主 上的另一个线程上阅读
- 我尝试在主
上没有 mainFor
的情况下在另一个线程上阅读
- 我尝试不使用
Thread.sleep
而不是 waitFor 来阅读
- 我尝试将
"/bin/bash", "-c", exec+" "+execFile
传递给 ProcessBuilder
- 我尝试使用 Runtime.exec 而不是 ProcessBuilder
- 我试过了
"/bin/bash", "-c", "while :; do echo 1; done"
。这实际上打破了 380k 字节的限制,并且像预期的那样无限地前进。
这是怎么回事,我该如何解决?
P.S。 unix 可执行文件的来源是 here,但我认为它不是很有用,因为它可以从 CMD
运行
我在打字时找到了答案。显然,您必须以某种方式同时处理 STDERR 和 STDOUT 流,它们不会消失。如果你只读其中一个而忽略另一个,最终被忽略的缓冲区会变得太大并阻塞直到它被清空。
所以添加下面的代码就解决了
new Thread( () -> {
try (InputStream es = csvBuilder.getErrorStream() ){
IOUtils.skip(es, Long.MAX_VALUE);
} catch (IOException e) {
throw new RuntimeException(e);
}
}).start();
我需要 运行 来自 java 运行ning 的 unix 程序 windows。 unix 程序将文件名作为第一个参数,处理该文件,并且 returns stdout 上的处理文件。
以下命令在 CMD 控制台中完美运行:
wsl.exe /home/user/process /mnt/c/Users/user/input
它将标准输出和标准错误打印到控制台;或者我可以将 stdout 重定向到一个新文件,该文件的重量为 1.2MB。
我想从 Java 做同样的事情。下面的代码是最简化的版本
ProcessBuilder toCsv = new ProcessBuilder("wsl.exe", "/home/user/process", "/mnt/c/Users/user/input");
Process proc = toCsv.start();
try (InputStream is = proc.getInputStream()){
for(int i=0; is.read() != -1; i++) {
System.out.println(i);
}
}
这总是在字节号 380927 上停止。调试器显示它在 FileInputStream.read
上停止- 我试过使用重定向将标准输出发送到文件
- 我试过只读取 stderr
- 我尝试在
waitFor
主 上的另一个线程上阅读
- 我尝试在主 上没有
- 我尝试不使用
Thread.sleep
而不是 waitFor 来阅读
- 我尝试将
"/bin/bash", "-c", exec+" "+execFile
传递给 ProcessBuilder - 我尝试使用 Runtime.exec 而不是 ProcessBuilder
- 我试过了
"/bin/bash", "-c", "while :; do echo 1; done"
。这实际上打破了 380k 字节的限制,并且像预期的那样无限地前进。
mainFor
的情况下在另一个线程上阅读
这是怎么回事,我该如何解决?
P.S。 unix 可执行文件的来源是 here,但我认为它不是很有用,因为它可以从 CMD
运行我在打字时找到了答案。显然,您必须以某种方式同时处理 STDERR 和 STDOUT 流,它们不会消失。如果你只读其中一个而忽略另一个,最终被忽略的缓冲区会变得太大并阻塞直到它被清空。
所以添加下面的代码就解决了
new Thread( () -> {
try (InputStream es = csvBuilder.getErrorStream() ){
IOUtils.skip(es, Long.MAX_VALUE);
} catch (IOException e) {
throw new RuntimeException(e);
}
}).start();