【发布时间】:2015-10-15 17:40:09
【问题描述】:
我正在用 java 编写一个包装程序,它只是应该通过在流中写入其标准并从其标准输出流中读取响应来将参数传递给其他进程。但是,当我尝试传入的String 太大时,PrintWriter.print 只会阻塞。没有错误,只是冻结。有没有好的解决方法?
相关代码
public class Wrapper {
PrintWriter writer;
public Wrapper(String command){
start(command);
}
public void call(String args){
writer.println(args); // Blocks here
writer.flush();
//Other code
}
public void start(String command) {
try {
ProcessBuilder pb = new ProcessBuilder(command.split(" "));
pb.redirectErrorStream(true);
process = pb.start();
// STDIN of the process.
writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), "UTF-8"));
} catch (Exception e) {
e.printStackTrace();
System.out.println("Process ended catastrophically.");
}
}
}
如果我尝试使用
writer.print(args);
writer.print("\n");
它可以在冻结之前处理更大的字符串,但最终仍会锁定。
是否有缓冲流的方法来解决这个问题? print 是否阻塞了具有足够空间的进程流?
更新
针对一些答案和 cmets,我提供了更多信息。
- 操作系统为 Windows 7
- BufferedWriter 会减慢运行时间,但最终并没有阻止它阻塞。
- 字符串可能会变得很长,长达 100,000 个字符
- 进程输入被消耗,但按行,即 Scanner.nextLine();
测试代码
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import ProcessRunner.Wrapper;
public class test {
public static void main(String[] args){
System.out.println("Building...");
Wrapper w = new Wrapper("java echo");
System.out.println("Calling...");
String market = "aaaaaa";
for(int i = 0; i < 1000; i++){
try {
System.out.println(w.call(market, 1000));
} catch (InterruptedException | ExecutionException
| TimeoutException e) {
System.out.println("Timed out");
}
market = market + market;
System.out.println("Size = " + market.length());
}
System.out.println("Stopping...");
try {
w.stop();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Stop failed :(");
}
}
}
测试过程:
您必须先编译此文件,并确保 .class 与测试 .class 文件位于同一文件夹中
import java.util.Scanner;
public class echo {
public static void main(String[] args){
while(true){
Scanner stdIn = new Scanner(System.in);
System.out.println(stdIn.nextLine());
}
}
}
【问题讨论】:
-
你似乎知道缓冲,所以你为什么不尝试使用
BufferedWriter? -
@Dici 我不太确定如何从 String 对象转到 BufferedWriter,也不确定这是否能解决问题,所以一直在努力解决这个问题,直到我明白了一点确认或指导。你觉得这样能解决问题吗?
-
@Cain 毕竟
BufferedWriter的API 是documented。 -
我想尝试重现该问题。问:什么是操作系统(Linux?Windows?其他?) 问:字符串有多长? 100个字? 1000个? 64,000 个字符(或更长)? ALSO:坦率地说,认为尝试缓冲写入器是个好主意。
-
@EJP 我确实尝试过 BufferedWriter,但运行时间较慢,仍然被阻塞
标签: java printwriter