如何将大输出写入Process getOutputStream?

我正在尝试使用ProcessBuilder和Process执行命令(例如ps -ef | grep apache)。 只要’ps -ef’的输出很小,代码就可以工作。 但如果输出太大,程序就会挂起。 有没有办法来解决这个问题? 这是基于[ http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html]的代码

#### Program.java #### import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; public class Program { private List command; public Program(String commandString) throws IOException { this(commandString, null); } public List getCommand() { return this.command; } private void setCommand(String filename, String location, String commandString, List parameters) throws IOException { if(filename != null) { commandString = new File(location, filename).getCanonicalPath(); } this.command = Collections.synchronizedList(new ArrayList()); this.command.add(commandString); if (parameters != null) { for (String arg: parameters) { command.add(arg); } } } public String[] run() throws IOException, InterruptedException { return this.run(null); } public String[] run(String input) throws IOException, InterruptedException { ProcessBuilder processBuilder = new ProcessBuilder(this.command); List commandList = processBuilder.command(); Process process = processBuilder.start(); if(input != null) { PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(process.getOutputStream())), true); writer.println(input); writer.flush(); writer.close(); } process.getOutputStream().close(); Gobbler outGobbler = new Gobbler(process.getInputStream()); Gobbler errGobbler = new Gobbler(process.getErrorStream()); Thread outThread = new Thread(outGobbler); Thread errThread = new Thread(errGobbler); outThread.start(); errThread.start(); outThread.join(); errThread.join(); int exitVal = process.waitFor(); System.out.println("PROCESS WAIT FOR: " + exitVal); List output = outGobbler.getOuput(); return output.toArray(new String[output.size()]); } } #### CommandExecutor.java #### import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; public class CommandExecutor { public List<List> programs; public static void main(String[] args) { try { CommandExecutor ce = new CommandExecutor(args[0]); String output = ce.run(); System.out.println("Command: " + args[0]); System.out.println("Output: " + output); } catch (IOException e) { // TODO Auto-generated catch block System.out.println(e.getLocalizedMessage()); e.printStackTrace(); } catch (InterruptedException ie) { // TODO Auto-generated catch block System.out.println(ie.getLocalizedMessage()); ie.printStackTrace(); } } public CommandExecutor(String command) throws IOException { this.setPrograms(command); } private void setPrograms(String command) throws IOException { this.programs = new ArrayList<List>(); //String cmdstring = ""; String[] commands = command.split("\\s*;\\s*"); for(String c: commands) { //String subcmdstr = ""; String file = null; String[] chainedCommands = c.split("\\s*\\|\\s*"); String lastCmd = chainedCommands[chainedCommands.length-1]; String[] fileCmd = lastCmd.split("\\s*>\\s*"); if(fileCmd.length > 1) { chainedCommands[chainedCommands.length-1] = fileCmd[0]; file = fileCmd[1]; } List l = new ArrayList(); for(String p: chainedCommands) { /*if(subcmdstr.equals("")) { subcmdstr = p; } else { subcmdstr += " redirects to " + p; }*/ String[] cmdparams = p.split(" "); String cmd = cmdparams[0]; List params = new ArrayList(); for(int j = 1; j < cmdparams.length; j++) { params.add(cmdparams[j]); } Program prog = new Program(cmd, params); l.add(prog); } if(file != null) { //subcmdstr += " redirects to file: " + file; l.add(file); } this.programs.add(l); //cmdstring += "new command: " + subcmdstr + "\n"; } //System.out.println("Actual Command: " + command); //System.out.println("Command String:\n" + cmdstring); } public String run() throws IOException, InterruptedException { String output = ""; for(List l: this.programs) { String[] out = new String[0]; int count = 0; boolean filenotfound = true; for(Object o: l) { if(o instanceof Program) { Program p = (Program) o; if(count == 0) { out = p.run(); } else { out = p.run(CommandExecutor.arrayToString(out)); } } else if(o instanceof String) { PrintWriter f = new PrintWriter(new File((String)o)); f.print(CommandExecutor.arrayToString(out)); f.close(); filenotfound = false; } count++; } if(filenotfound) { output += CommandExecutor.arrayToString(out); } } return output; } public static String arrayToString(String[] strArray) { String str = ""; for(String s: strArray) { str += s; } return str; } } 

谢谢,

奎德

好的,我搞定了。 下面是代码,给定一个命令列表,它将一个命令的输出传递给下一个命令。

 /* ####### PipeRedirection.java */ import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; public class PipeRedirection { public static void main(String[] args) throws FileNotFoundException { if(args.length < 2) { System.err.println("Need at least two arguments"); System.exit(1); } try { String input = null; for(int i = 0; i < args.length; i++) { String[] commandList = args[i].split(" "); ProcessBuilder pb = new ProcessBuilder(commandList); //pb.redirectErrorStream(true); Process p = pb.start(); if(input != null) { PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true); writer.println(input); writer.flush(); writer.close(); } InputProcess.Gobbler outGobbler = new InputProcess.Gobbler(p.getInputStream()); InputProcess.Gobbler errGobbler = new InputProcess.Gobbler(p.getErrorStream()); Thread outThread = new Thread(outGobbler); Thread errThread = new Thread(errGobbler); outThread.start(); errThread.start(); outThread.join(); errThread.join(); int exitVal = p.waitFor(); System.out.println("\n****************************"); System.out.println("Command: " + args[i]); System.out.println("Exit Value = " + exitVal); List output = outGobbler.getOuput(); input = ""; for(String o: output) { input += o; } } System.out.println("Final Output:"); System.out.println(input); } catch (IOException ioe) { // TODO Auto-generated catch block System.err.println(ioe.getLocalizedMessage()); ioe.printStackTrace(); } catch (InterruptedException ie) { // TODO Auto-generated catch block System.err.println(ie.getLocalizedMessage()); ie.printStackTrace(); } } public static class Gobbler implements Runnable { private BufferedReader reader; private List output; public Gobbler(InputStream inputStream) { this.reader = new BufferedReader(new InputStreamReader(inputStream)); } public void run() { String line; this.output = new ArrayList(); try { while((line = this.reader.readLine()) != null) { this.output.add(line + "\n"); } this.reader.close(); } catch (IOException e) { // TODO System.err.println("ERROR: " + e.getMessage()); } } public List getOuput() { return this.output; } } } 

不要将它作为String打印,而是为CommandExecuter提供一个可选的OutputStream(在你的Case中,你将System.out作为参数传递)并将其写入该流。

在当前程序中,Main方法将执行程序,并且在run方法返回某些内容之前不会打印任何内容(挂起)。