2012-11-15 160 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