减少java代码中打开文件的数量

ykh*_*lev 5 java io java-io

嗨,我有一些使用块的代码

RandomAccessFile file = new RandomAccessFile("some file", "rw");
FileChannel channel = file.getChannel();

// some code
String line = "some data";
ByteBuffer buf = ByteBuffer.wrap(line.getBytes());
channel.write(buf);

channel.close();
file.close();
Run Code Online (Sandbox Code Playgroud)

但应用程序的具体内容是我必须生成大量临时文件,平均超过4000个(用于将Hive插入到分区表中).

问题是有时我会遇到异常

Failed with exception Too many open files
Run Code Online (Sandbox Code Playgroud)

在应用程序运行期间.

如果有任何方法告诉操作系统文件已经关闭并且不再使用了,为什么会这样

channel.close();
file.close();
Run Code Online (Sandbox Code Playgroud)

不会减少打开的文件数量.有没有办法在Java代码中执行此操作?

我已经增加了打开文件的最大数量

#/etc/sysctl.conf:
kern.maxfiles=204800
kern.maxfilesperproc=200000
kern.ipc.somaxconn=8096
Run Code Online (Sandbox Code Playgroud)

更新: 我试图消除这个问题,所以我分开了代码来调查它的每个部分(创建文件,上传到配置单元,删除文件).

使用"File"或"RandomAccessFile"类失败,但"打开的文件太多"除外.

最后我使用了代码:

FileOutputStream s = null;
FileChannel c = null;

try {
    s = new FileOutputStream(filePath);
    c = s.getChannel();
    // do writes
    c.write("some data"); 
    c.force(true);
    s.getFD().sync();

} catch (IOException e) {
    // handle exception
} finally {
    if (c != null)
        c.close();
    if (s != null)
        s.close();
}
Run Code Online (Sandbox Code Playgroud)

这适用于大量文件(在20K上测试,每个文件大小为5KB).代码本身不会像以前的两个类那样抛出异常.但是生产代码(带有配置单元)仍然有例外.而且似乎通过JDBC的hive连接就是它的原因.我会进一步调查.

小智 4

操作系统可以使用的打开文件句柄的数量与进程可以打开的文件句柄的数量不同。大多数 UNIX 系统限制每个进程的文件句柄数量。最有可能的是 JVM 的 1024 个文件句柄。

a) 您需要在启动 JVM 的 shell 中将 ulimit 设置为更高的值。(类似于“ulimit -n 4000”)

b) 您应该确认没有任何资源泄漏导致您的文件无法“最终确定”。