2

我正在尝试创建一个程序以在 Linux 服务器上按某个名称查找所有文件,然后将它们的绝对路径通过管道传输到 ArrayList 中进行处理。我使用 Process (with exec) 和 BufferedReader 的方法似乎适用于我的所有其他需求(各种其他命令 du -h df-h 等......)但是,它似乎并没有在这个工作如果我没有输出数据!它似乎正在执行,因为它需要一两分钟才能完成,但我从未看到任何数据结果。

这是代码:(没有try/catch,它只打印堆栈跟踪)

Process process = 
    Runtime.getRuntime().exec("find " + Main.serversPath + " -name 'dynmap'");
BufferedReader stdInput = new BufferedReader(
    new InputStreamReader(process.getInputStream()));

while ((s = stdInput.readLine()) != null) {
    filesToDelete.add(s);

    if (Main.debugMode == "High") {
        System.out.println("Preprocess: dynmap pass - found " + s);
    }
}

process.destroy();
4

3 回答 3

1

您应该始终在单独的线程(使用 StreamGobbler)中捕获进程的错误流,以处理进程抛出错误的情况。

class StreamGobbler extends Thread
{
    private InputStream is;
    private String myMessage;

    public StreamGobbler(InputStream istream)
    {
        this.is = istream;
    }

    public String getMessage()
    {
        return this.myMessage;
    }

    @Override
    public void run()
    {
        StringBuilder buffer = new StringBuilder();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        int size = 1024 * 1024;
        char[] ch = new char[size];
        int read = 0;
        try {
            while ((read = br.read(ch, 0, size)) >= 0) {
                buffer.append(ch, 0, read);
            }
        }
        catch (Exception ioe) {
            ioe.printStackTrace();
        }
        finally {
            try {
                br.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        this.myMessage = buffer.toString();
        return;
    }
}

然后你应该使用 StreamGobbler 来捕获错误流,如下所示:

Process process = 
    new ProcessBuilder("find", Main.serversPath, "-name", "'dynmap'").start();

StreamGobbler error = new StreamGobbler(process.getErrorStream());
error.start();

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

while ((s = stdInput.readLine()) != null) {
    filesToDelete.add(s);

    if (Main.debugMode.equals("High")) {
        System.out.println("Preprocess: dynmap pass - found " + s);
    }
}

// Get the exit status
int exitStatus = process.waitFor();
if (exitStatus != 0) {
    // read the error.getMessage() and handle accordingly.
}
process.destroy();

另外,推荐使用ProcessBuilder来创建流程。

于 2012-12-20T02:07:18.080 回答
1

这一行:

System.out.println("Preprocess: dynmap pass - found " + s);

很可能不会被执行。

当用于字符串时,==运算符比较对象引用而不是值。

为了比较实际值,您应该使用以下String.equals()方法:

if (Main.debugMode.equals("High")) {
    System.out.println("Preprocess: dynmap pass - found " + s);
}

有关在 Java 中比较对象的概述,请参见此处

于 2012-12-20T02:06:48.670 回答
0

我认为您的问题是您没有关闭 BufferedRreader。您应该始终关闭,如果需要,请刷新您的流。所以:

    Process process = Runtime.getRuntime().exec("find " + Main.serversPath + " -name 'dynmap'");
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));

    while ((s = stdInput.readLine()) != null) {
        filesToDelete.add(s);

        if (Main.debugMode == "High") {
            System.out.println("Preprocess: dynmap pass - found " + s);
        }
    }
    process.destroy();
    //Add this line here!
    stdInput.close();

您可能还想更改此设置:

    if (Main.debugMode == "High") {
            System.out.println("Preprocess: dynmap pass - found " + s);
    }

对此:

   if (Main.debugMode.equals("High")) {
            System.out.println("Preprocess: dynmap pass - found " + s);
   }
于 2012-12-20T01:55:54.710 回答