在 Java 中将文件作为命令行参数传递

Passing a file as a Commandline argument in Java

我正在尝试在给定文件的命令行中编写一个 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 而不是使用“~”来正确完成。

我相信你会发现 ~ 没有被正确打断(它被认为是一个文字,没有被 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