2012-11-15 159 views
4

我已經花了3天,沒有太多的運氣在谷歌上如何從Java內部運行grep進程。從Java程序運行grep

我有下面的代碼來運行一個grep進程,但是,我只得到響應的第一行。

package com.example.parser; 


import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 

public class Main { 

    public static void main(String[] args) { 
     try { 
      Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/").start(); 

      BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); 

      String line = ""; 
      while((line = br.readLine()) != null) { 
       System.out.println(line); 
      } 

      System.out.println("Exit Code: " + process.exitValue()); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

我只得到如下回應:

Binary file /home/user/dev/java/Parser/parser/bin/com/example/parser/Main.class matches 
Exit Code: 0 

當我應該得到如下回應:

Binary file /home/user/dev/java/Parser/parser/com/example/parser/Main.class matches 
/home/user/dev/java/Parser/parser/src/com/example/parser/Main.java:10: public static void main(String[] args) { 
/home/user/dev/java/Parser/parser/src/com/example/parser/Main.java:12:   Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start(); 
Exit Code: 0 

我很奇怪,爲什麼我只得到輸出爲首次發現?是grep分叉幾個進程來運行搜索,我只得到第一個處理?


我也試圖從一個線程運行的進程:

包com.example.parser;

public class Main { 

    public static void main(String[] args) { 
     try { 
      Analyzer analyzer = new Analyzer(); 
      analyzer.start(); 
      analyzer.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 


package com.example.parser; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 

public class Analyzer extends Thread { 

    public Analyzer() { 
    } 

    @Override 
    public void run() { 
     try { 
      Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start(); 
      process.waitFor(); 
      BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); 

      String line = ""; 
      while((line = br.readLine()) != null) { 
       System.out.println(line); 
      } 

      System.out.println("Exit Code: " + process.exitValue()); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

還有以下幾點:

package com.example.parser; 

import java.io.IOException; 

public class Main { 

    public static void main(String[] args) { 
     try { 
      Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start(); 
      process.waitFor(); 

      Analyzer analyzer_is = new Analyzer(process.getInputStream()); 
      Analyzer analyzer_es = new Analyzer(process.getErrorStream()); 

      analyzer_is.start(); 
      analyzer_es.start(); 

      analyzer_is.join(); 
      analyzer_es.join(); 

      System.out.println("Exit Code: " + process.exitValue()); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

package com.example.parser; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 

public class Analyzer extends Thread { 

    InputStream is = null; 

    public Analyzer(InputStream is) { 
     this.is = is; 
    } 

    @Override 
    public void run() { 
     try { 
      BufferedReader br = new BufferedReader(new InputStreamReader(this.is)); 

      String line = ""; 
      while((line = br.readLine()) != null) { 
       System.out.println(line); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

由於建議通過以下文章:http://www.javaworld.com/jw-12-2000/jw-1229-traps.html

+1

是否有除了學習如何使用'ProcessBuilder'的終極目標? –

+0

@Dave:不確定你的問題是什麼意思? – ossys

+0

沒錯,如果你想用Java代碼做一些事情,尤其是像名字所暗示的「解析」的東西,不知道你爲什麼要這樣做。換句話說,如果你的最終目標是某種形式的Java程序操作,你爲什麼要這樣做? –

回答

2

我能通過啓動帶-c標誌的shell來解決問題。下面的代碼做什麼,我原本打算:

package com.example.parser; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

public class Main { 

    public static void main(String[] args) { 
     try { 
      List<String> commands = new ArrayList<String>(); 
      commands.add("/bin/sh"); 
      commands.add("-c"); 
      commands.add("grep -rni --include \"*.java\" \"public static void main(\" /home/user/dev/java/Parser/parser"); 

      Process process = new ProcessBuilder(commands).start(); 
      Analyzer analyzer_is = new Analyzer(process.getInputStream()); 
      Analyzer analyzer_es = new Analyzer(process.getErrorStream()); 

      analyzer_is.start(); 
      analyzer_es.start(); 

      process.waitFor(); 

      analyzer_is.join(); 
      analyzer_es.join(); 

      System.out.println("Exit Code: " + process.exitValue()); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 


package com.example.parser; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 

public class Analyzer extends Thread { 

    InputStream is = null; 

    public Analyzer(InputStream is) { 
     this.is = is; 
    } 

    @Override 
    public void run() { 
     try { 
      BufferedReader br = new BufferedReader(new InputStreamReader(this.is)); 

      String line = ""; 
      while((line = br.readLine()) != null) { 
        System.out.println(line); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
1

這可能是因爲你不等待grep來完成。

使用the waitFor method

Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/").start(); 
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); 
process.waitFor(); 
String line = ""; 
while((line = br.readLine()) != null) { 
     System.out.println(line); 
} 

請注意,還可以讀取輸出(主要是爲了得到什麼情況),而它正在使用

Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"",  String line; 
while (true) { 
    line = reader.readLine(); // add IO exception catching 
    if (line != null) { 
     System.out.println(line); 
    } else { 
     Thread.sleep(DELAY); // DELAY could be 100 (ms) for example  
    } 
} 

處理,我想你一定會的grep由java程序的所有者推出的長度超過一行?

+0

感謝您的回覆!我也嘗試過(儘管它沒有顯示在我的例子中)。當我收到你的回覆時,我再次嘗試,但仍然沒有運氣。我也嘗試創建一個單獨的線程來創建進程並運行它,結果相同。我也嘗試創建一個只處理具有相同結果的BufferedReader對象的線程。 – ossys

+0

你看過ErrorStream嗎? –

+0

是的,我也捕獲了錯誤流。我有一個單獨的實現,我創建了一個線程來處理InputStream和一個處理ErrorStream。我現在會發布更新的代碼。 – ossys

0

其他原因可能是您的進程仍在運行,但您的Java程序剛剛退出。

使用process.waitFor();並在一個線程中讀取你的輸入流。

開始該過程。 用進程輸入流作爲輸入來處理線程。 現在等待進程退出通過使用process.waitFor();

這可能有幫助!

+0

感謝您的回覆!如果你看看我上面的一些編輯內容,我相信我已經嘗試了你所建議的相同結果......我已經創建了一個單獨的線程,我從中接受了grep進程的InputStream和ErrorStream ... – ossys