java - 缓冲读取器拒绝输出数据

标签 java process runtime exec bufferedreader

我正在尝试创建一个程序来查找 Linux 服务器上特定名称的所有文件,然后将它们的绝对路径通过管道传输到 ArrayList 中进行处理。我使用 Process (带有 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();

最佳答案

您应该始终在单独的线程中捕获进程的错误流(使用 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创建一个流程。

关于java - 缓冲读取器拒绝输出数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13964060/

相关文章:

c# - 如何确定进程对象正在运行

node.js - 在 Node js 中获取浏览器选项卡标题

java.io.IOException : error=13, 执行 .exe 库时权限被拒绝

Spring运行时对象/bean创建

Objective-C 运行时和内存管理

java - Cassandra 2.2.8 : sstableverify - GC overhead limit exceeded

java - Java 中的 CRL 验证

java - HTTPUrlConnection 和 application/octet-stream 内容类型响应处理

java - 使用 Jackson 将 Java8 LocalDateTime 序列化为 UTC 时间戳

docker - Kubernetes安装是否总是需要Docker?