【发布时间】:2011-05-24 15:11:55
【问题描述】:
您好,我有一些使用块的代码
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();
但应用程序的具体情况是我必须生成大量临时文件,平均超过 4000 个(用于 Hive 插入分区表)。
问题是有时我会捕获异常
Failed with exception Too many open files
在应用程序运行期间。
如果有什么方法可以告诉操作系统该文件已经关闭并且不再使用,我会问为什么
channel.close();
file.close();
不会减少打开文件的数量。有没有办法在 Java 代码中做到这一点?
我已经增加了打开文件的最大数量
#/etc/sysctl.conf:
kern.maxfiles=204800
kern.maxfilesperproc=200000
kern.ipc.somaxconn=8096
更新: 我试图消除这个问题,所以我分开了代码来调查它的每一部分(创建文件、上传到配置单元、删除文件)。
使用类 '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();
}
这适用于大量文件(在 20K 上测试,每个 5KB 大小)。代码本身不会像前两个类那样抛出异常。 但是生产代码(带有配置单元)仍然有例外。看来,通过 JDBC 的配置单元连接是它的原因。 我会进一步调查。
【问题讨论】:
-
听起来有些东西依赖终结器来关闭外部资源。那是……真是自找麻烦。