java.io.FileNotFoundException :/tmp/(Too many open files)

标签 java rest jax-ws jersey-2.0

我在 Java EE 中有一个休息服务,由于一些奇怪的向后兼容性原因,我必须在其中添加一些行后从 URL 请求返​​回 .mdb 文件。

起初,我只是打开一个 mdb 文件,清除其中的所有行,写入我的行并将其返回给调用者,但是我意识到 .mdb 一直以这种方式增长,因为 Access 不会在删除时清除行,而只会清除行删除它并且我正在使用的库(Jackcess)不支持完全清除行。

所以我转而使用 java.io.File.createTempFile() 创建一个空的 .mdb 文件的副本并返回它,但是留下了一个指向/tmp/文件夹中文件的悬空指针,几天后我得到了一个

java.io.FileNotFoundException: /tmp/tmpdb.mdb04949499 (Too many open files)

到目前为止我找到的唯一解决方案是:

  1. 将 MAX_FILE_HANDLES_FOR_READ_ENDS_MAP 设置为非常高的数字(只会推迟问题的发生)
  2. 删除临时文件,但是这是不可行的,因为我从函数返回它,并且一旦返回,我就失去了对指针的控制。

低于我目前拥有的:

GET
@Path("/get/database/{filename}")
@Produces("application/jet")
public StreamingOutput getDatabase(@PathParam("filename") String fileName)
{
   //access files increase indefinitely in size because deleted rows are simply marked "deleted" and not removed
   //so we create a temporary file equal to the template .mdb file and use it instead
   java.io.File myDBFile = null;
    try
    {
        java.io.File templateDBFile = new java.io.File(url + "resources/clean_tmpdb.mdb");
        myDBFile = java.io.File.createTempFile("tmpdb", ".mdb");
        myDBFile.deleteOnExit(); //useless hint
        FileChannel src = new FileInputStream(templateDBFile).getChannel();
        FileChannel dest = new FileOutputStream(myDBFile).getChannel();
        dest.transferFrom(src, 0, src.size());
    }
    catch (IOException ex)
    {
        Logger.getLogger(FileResource.class.getName()).log(Level.SEVERE, null, ex);
    }
finally
    {
        if (src != null)
        {
            try
            {
                src.close();
            }
            catch (IOException ex)
            {
                Logger.getLogger(FileResource.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        if (dest != null)
        {
            try
            {
                dest.close();
            }
            catch (IOException ex)
            {
                Logger.getLogger(FileResource.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

/* work on the file inserting rows */

return new FileStreamingOutput(myDBFile);
}

编辑:发现了一个类似的问题,但接受的答案模糊:How to delete file after REST response ,接受的答案是“直接写入响应中包含的输出流。”

最佳答案

您没有关闭 srcdest。为了确保它们关闭,请在 finally block 中关闭它们,或使用 try-with-resources 语法。

return new FileStreamingOutput(myDBFile);
/* here I should call myDBFile.close(); and myDBFile.delete(); */

这里你不能调用myDBFile.close(),因为没有这样的方法。您也不能调用myDBFile.delete(),否则调用者将收到一个不存在的File。如果需要删除File,则调用者必须执行此操作。您所说的要求没有意义。

关于java.io.FileNotFoundException :/tmp/(Too many open files),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29768403/

相关文章:

node.js - NodeJS返回值时出现循环结构错误

java - 当部分访问器元素通过 namespace 限定时,JAX WS Web 服务接收 null 参数

java - 如何使用 JAX-WS/JAXB 编码参数化类型?

java - 如何修改整个 ProgressBar?

java - 错误 - 错误的请求;检查错误消息以获取详细信息

javascript - 处理具有大数据的 XMLHttpRequest 响应

java - 通过 REST API : allocatedMB, allocatedVcores 和 runningContainers 的 Hadoop 指标始终为 -1

java - Jersey 中的 jax-ws 调用

java - 字段初始化时,为什么 "this"不为null并且所有方法都可以调用? "this"指的是什么?

java - org.apache.lucene.store.LockObtainFailedException : Lock obtain timed out: NativeFSLock@/var/database/schema/label/lucene/write. 锁