2009-07-01 6 views
3

ProcessBuilderとProcessを使用してコマンド(例:ps -ef | grep apache)を実行しようとしています。このコードは 'ps -ef'の出力が小さい限り動作します。しかし、出力が大きすぎると、プログラムがハングします。これを修正する方法はありますか?ここに私のコード[http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html]Process getOutputStreamに大きな出力を書き込むにはどうすればよいですか?

#### 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<String> command; 

     public Program(String commandString) throws IOException { 
      this(commandString, null); 
     } 

     public List<String> getCommand() { 
      return this.command; 
     } 

     private void setCommand(String filename, String location, String commandString, List<String> parameters) throws IOException { 
      if(filename != null) { 
       commandString = new File(location, filename).getCanonicalPath(); 
      } 

      this.command = 
       Collections.synchronizedList(new ArrayList<String>()); 

      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<String> 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<String> 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<Object>> 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<Object>>(); 

     //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<Object> l = new ArrayList<Object>(); 
      for(String p: chainedCommands) { 
       /*if(subcmdstr.equals("")) { 
        subcmdstr = p; 
       } 
       else { 
        subcmdstr += " redirects to " + p; 
       }*/ 
       String[] cmdparams = p.split(" "); 
       String cmd = cmdparams[0]; 
       List<String> params = new ArrayList<String>(); 
       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<Object> 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; 
    } 
} 

おかげで、

Quadir

答えて

3

文字列としてそれを印刷しますが、あなたのケースではあなたが合格(CommandExecuterにオプションのOutputStreamを与えてはいけないのSystem.outに基づいています引数として)、そのストリームに書き込みます。

現在のプログラムでは、メインメソッドはプログラムを実行し、実行メソッドが何かを返すまで何も印刷しません(ハング)。

+1

DAFF、 ご回答をお寄せいただきありがとうございますしかし、あなたは手の込んだことができます。私はあなたの答えをよく理解していませんでした。 - Quadir – Quadir

+1

申し訳ありませんが...十分に速くはありませんでした。あなたのソリューションはかなり良いようだ:) – Daff

5

わかりました。以下はコードであり、コマンドのリストがあれば、あるコマンドの出力を次のパイプにパイプします。

/* 
####### 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<String> 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<String> output; 

     public Gobbler(InputStream inputStream) { 
      this.reader = new BufferedReader(new InputStreamReader(inputStream)); 
     } 

     public void run() { 
      String line; 
      this.output = new ArrayList<String>(); 
      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<String> getOuput() { 
      return this.output; 
     } 
    } 
} 
関連する問題