Java Process Builder waitFor() 问题和打开文件限制

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1129441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:04:20  来源:igfitidea点击:

Process Builder waitFor() issue and Open file limitations

javajava-ioprocessbuilder

提问by Louis

I have inherited some code:

我继承了一些代码:

Process p = new ProcessBuilder("/bin/chmod", "777", path).start();
p.waitFor();

Basically, there is for some ancient and highly voodoo based reason for storing key/value pairs on disk as files. I don't really want to go into it.

基本上,将键/值对作为文件存储在磁盘上有一些古老且高度基于巫毒教的原因。我真的不想进去。

However, I am left with a bunch of IO exceptions:

但是,我留下了一堆 IO 异常:

Exception :Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files
Message: Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files

And by a bunch I mean in the realms of 10k - millions

一堆我的意思是在 10k 的领域 - 数百万

I get the feeling the waitFor call was to stop these from occurring waiting for the process to complete it and exit back, however I think the chmod is returning a result before the file is actually closed. Does anyone know if that would be the cause of these exceptions?

我觉得 waitFor 调用是为了阻止这些发生,等待进程完成它并退出,但是我认为 chmod 在文件实际关闭之前返回结果。有谁知道这是否是这些异常的原因?

My other inclination is that the opening and closing of thousands of files is not happening quickly enough on the java end and that there is something else going on, maybe something like that there is some form of file buffer that isn't getting cleared out when fw.close() is being called.

我的另一个倾向是,在 java 端打开和关闭数千个文件的速度不够快,而且还有其他事情正在发生,也许是某种形式的文件缓冲区在什么时候没有被清除fw.close() 正在被调用。

I am pretty new to java and this was a hell weird one that has me stumped. (gladly the app still runs somehow.. after spitting out a very large log file that is)

我对 Java 很陌生,这是一个让我难倒的地狱怪异。(很高兴应用程序仍然以某种方式运行......在吐出一个非常大的日志文件之后)

Can anyone else think of a way to get around this, clearing buffers or increasing the files open limit to something where the jvm can keep up with itself (assuming that is the problem)

其他任何人都可以想出一种方法来解决这个问题,清除缓冲区或将文件打开限制增加到 jvm 可以跟上自己的程度(假设这是问题所在)

采纳答案by Vinay Sajip

I presume you are running these chmod commands in a loop - otherwise I don't see why you'd get so many exceptions. It's possible that you're hitting a deadlock because you're not reading the output of the spawned processes. That certainly used to bite me back in the pre-ProcessBuilder, Runtime.exec()days.

我假设您正在循环中运行这些 chmod 命令 - 否则我不明白为什么您会收到这么多异常。您可能会遇到死锁,因为您没有读取衍生进程的输出。在前几天ProcessBuilder,这肯定曾经让我反感Runtime.exec()

Change your code snippet to the above pattern:

将您的代码片段更改为上述模式:

try {
    ProcessBuilder pb = new ProcessBuilder("/bin/chmod", "777", path);    
    pb.redirectErrorStream(true); // merge stdout, stderr of process

    Process p = pb.start();
    InputStreamReader isr = new  InputStreamReader(p.getInputStream());
    BufferedReader br = new BufferedReader(isr);

    String lineRead;
    while ((lineRead = br.readLine()) != null) {
        // swallow the line, or print it out - System.out.println(lineRead);
    }

    int rc = p.waitFor();
    // TODO error handling for non-zero rc
}
catch (IOException e) {
    e.printStackTrace(); // or log it, or otherwise handle it
}
catch (InterruptedException ie) {
    ie.printStackTrace(); // or log it, or otherwise handle it
} 

(credit: this site) and see if that helps the situation.

(信用:本网站),看看这是否有助于这种情况。

回答by jsight

It seems unlikely that the process would actually complete without closing the files. Could this be happening in a very large # of threads? Or perhaps some of them are not actually completing (ie, it is hanging at waitFor in some cases)?

在不关闭文件的情况下,该过程似乎不太可能真正完成。这会发生在非常大的线程中吗?或者其中一些实际上并没有完成(即,在某些情况下它挂在 waitFor 上)?

Otherwise, I think you will be stuck with increasing the open files limit. Assuming that this is a Unix-like system, the "ulimit" command is probably what you are looking for.

否则,我认为您会被增加打开文件限制所困扰。假设这是一个类 Unix 系统,“ulimit”命令可能就是你要找的。

回答by Ryan Fernandes

If you're using JAVA 6, you could also try the new setters (for read,write,execute) on the File object. Might be slower, but it should work.

如果您使用的是 JAVA 6,您还可以在 File 对象上尝试新的 setter(用于读取、写入、执行)。可能会更慢,但它应该可以工作。

回答by Louis

Thanks for the help guys, this should sort out a load of weirdness going on elsewhere because of it.

感谢您的帮助,这应该可以解决其他地方因此而发生的一系列怪异现象。

Using your(Vinay) example and the stream closings:

使用您的(Vinay)示例和流关闭:

try{ 
  fw.close();

  ProcessBuilder pb = new ProcessBuilder("/bin/chmod", "777", path);

  pb.redirectErrorStream(true); // merge stdout, stderr of process
  p = pb.start();

  InputStreamReader isr = new  InputStreamReader(p.getInputStream());
  BufferedReader br = new BufferedReader(isr);

  String lineRead;
  while ((lineRead = br.readLine()) != null) {
    // swallow the line, or print it out - System.out.println(lineRead);
  }

} catch (Exception ioe) {
  Logger.logException(Logger.WARN, ioe.getMessage(), ioe);
} finally {
  try {
    p.waitFor();//here as there is some snipped code that was causing a different
                // exception which stopped it from getting processed

    //missing these was causing the mass amounts of open 'files'
    p.getInputStream().close();
    p.getOutputStream().close();
    p.getErrorStream().close(); 

  } catch (Exception ioe) {
    Logger.logException(Logger.WARN, ioe.getMessage(), ioe);
  }
}

Got the idea from John B Mathews post.

从约翰 B 马修斯的帖子中得到了这个想法。