在Java

时间:2015-06-26 00:58:53

标签: java command-line command-line-arguments

我试图用Java编写一个程序,在命令行中对给定文件运行pdfgrep,但是我无法让它执行。

我已经写了以下代码:

public class PDFGrepCall {
public static void main(String[] args) throws IOException, InterruptedException{
    PDFGrepCall obj = new PDFGrepCall();

    String searchterm = "git";
    String filename = "~/Documents/COMP2100/03git.slides.pdf";
    String newsearch = "'"+searchterm+"'";
    String command="pdfgrep -c "+newsearch+" "+filename;
    System.out.println(command);

    StringBuffer output = new StringBuffer();
    Process p;

    p=Runtime.getRuntime().exec(command);
    p.waitFor();

    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line = reader.readLine();
    while ((line=reader.readLine())!=null) {
         output.append(line+"\n");
         }

    System.out.println(output.toString());

    }

这应该打印我写的命令,并在新行上打印命令的结果(在这种情况下,数字57)。但是,当我运行它时,程序不会给我命令的结果,只是在命令后打印一个换行符并终止。

我可以确认java之外的命令本身工作得很好,并且该文件存在于给定的位置。

我是否错过了将文件参数从Java传递到命令行函数的错误?我应该怎么做才能正确执行这项任务?

编辑:解决方案如下。它应该与processbuilder正确完成,并将目录更改为home而不是使用"〜"。

1 个答案:

答案 0 :(得分:1)

我相信你会发现~没有被正确中断(它被视为文字并且没有被exec函数扩展)

例如,如果我使用类似......

的东西
    ProcessBuilder pb = new ProcessBuilder("ls", "~");
    pb.redirectErrorStream(true);

    try {
        Process p = pb.start();
        InputStream is = null;
        try {
            is = p.getInputStream();
            int in = -1;
            while ((in = is.read()) >= 0) {
                System.out.print((char) in);
            }
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e) {
            }
        }
        System.out.println("Exited with " + p.waitFor());
    } catch (IOException exp) {
        exp.printStackTrace();
    } catch (InterruptedException exp) {
        exp.printStackTrace();
    }

输出:

ls: cannot access ~: No such file or directory
Exited with 2

但如果我将其改为

ProcessBuilder pb = new ProcessBuilder("ls");

它工作正常。

如果您需要用户主目录,那么您需要使用System.getProperty("user.home")自行中断它,例如

ProcessBuilder pb = new ProcessBuilder("ls", System.getProperty("user.home"));

我还强烈建议使用ProcessBuilder,它允许您将错误流重定向到InputStream(以及其他地方),这将使生活更轻松并更改"工作"执行进程的目录,它还可以更好地处理带空格的参数,这意味着你可以做类似......

的操作
ProcessBuilder pb = new ProcessBuilder("ls");
pb.directory(new File(System.getProperty("user.home")));

并获得与之前相同的结果

进一步测试......

没有安装pdfgrep,我想我可能会尝试grep

ProcessBuilder pb = new ProcessBuilder("grep", "-i", "banana", "~/Test.txt");

导致

grep: ~/Test.txt: No such file or directory
Exited with 2

(是的,Test.txt在主目录中)

当我将其更改为

ProcessBuilder pb = new ProcessBuilder("grep", "-i", "banana", "Test.txt");
pb.directory(new File(System.getProperty("user.home")));

导致了

Bananas are yellow
Exited with 0