2009-07-15 27 views
9

我继承了一些代码:进程生成WAITFOR()问题,并打开文件限制

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

基本上,是一些古老的和高度巫术基于原因在磁盘上存储键/值对的文件。我真的不想进入它。

不过,我留下了一堆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 

而且一帮我的意思是在10K的领域 - 数以百万计

给我的感觉的WAITFOR电话是停止这些从等待进程完成并退出,但我认为chmod在文件实际关闭之前返回结果。有谁知道这是否会成为这些例外的原因?

我的另一个倾向是,成千上万的文件的打开和关闭在java端没有足够快地发生,并且还有其他事情正在发生,也许类似于某种形式的文件缓冲区不是当fw.close()被调用时被清除。

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

其他人可以想到一种方法来解决这个问题,清理缓冲区或增加文件打开限制的东西,jvm可以保持自己(假设这是问题)

+0

什么是您的目标操作系统(和版本)。看到这个:http://unix.derkeiler.com/Newsgroups/comp.unix.solaris/2007-02/msg00873.html – 2009-07-15 06:21:11

+0

debian,它似乎被清除出uname。将是最新的稳定。 – Louis 2009-07-15 21:24:58

回答

14

我认为你正在循环中运行这些chmod命令 - 否则我不明白为什么你会得到这么多的异常。您可能因为没有读取衍生进程的输出而导致死锁。那肯定会在前ProcessBuilder,Runtime.exec()天内咬我。

更改您的代码段以上模式:

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 
} 

(来源:this site),看看有没有什么帮助的情况。

+0

试过这个,发生了同样的例外 – Louis 2009-07-15 23:04:46

0

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

否则,我认为你会被卡在增加打开的文件限制。假设这是一个类Unix系统,那么“ulimit”命令可能就是你正在寻找的。

+0

设置为无限:\ – Louis 2009-07-15 21:26:56

0

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

6

感谢你们的帮助,这应该能够解决因为它而在别处发生的一系列奇怪现象。

使用您的(维奈)例如和流倒闭:

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); 
    } 
} 

上心从约翰·B·马修斯post