【问题标题】:Java File handles won't closeJava 文件句柄不会关闭
【发布时间】:2013-08-22 23:15:42
【问题描述】:

是的这个问题之前已经被问过,但是这个问题看起来有点复杂。我已经使用了之前与此相关的问题中的所有解决方案。

涉及: Freeing Java File Handles , Java keeps file locks no matter what

package me.test;

import java.io.File;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class Test {
    Logger log = Logger.getAnonymousLogger();
    FileHandler handle;

    final static String newline = System.lineSeparator();
    /**
     * @param args
     */
    public static void main(String[] args) {
        Test t = new Test();
        t.run();
    }
    public void run()
    {
        for (int i = 0; i < 6; i++) {
            testLogs();
            change();
        }
        testLogs();
        if (handle != null)
        {
            handle.close();
            log.removeHandler(handle);
        }
    }
    public static FileHandler craftFileHandler(File file, boolean append)
    {
        if (file == null)
            return null;
        FileHandler fh = null;
        try {
            fh = new FileHandler(file.getPath(), append);
            fh.setFormatter(new Formatter() {

                @Override
                public String format(LogRecord record) {
                    return "[test] " + "[" + record.getLevel().toString() + "]" + String.format(record.getMessage(), record.getParameters()) + newline;
                }
            });
            return new FileHandler(file.getPath(), append);
        } catch (Exception e) {
            if (fh != null)
                fh.close();
            return null;
        } 
    }

    public void change()
    {
        if (handle != null)
        {
            handle.flush();
            handle.close();
            log.removeHandler(handle);
        }
        handle = null;
        File f = new File("log.log");
        handle = craftFileHandler(f, true);
        System.out.println(f.getAbsolutePath());
        if (handle != null)
            log.addHandler(handle);
    }
    public void testLogs()
    {
        if (log == null)
        {
            log = Logger.getLogger("test");
            log.setLevel(Level.ALL);
        }
        log.info("This is info #1");
        log.warning("Warning 1");
        log.info("meh info again.");
        log.severe("SEVERE HELL YA NICE TEST");
        log.info("You sure its good here?");
        log.info("Handler count " + log.getHandlers().length);
    }
}

此代码旨在作为测试代码。我制作了这个测试文件,以便弄清楚如何在我的项目中解决这个问题。

我有一个循环的原因是因为问题发生得太快而无法解释。因此,循环是模拟它的最佳方式。在我的项目中,有一个日志文件的配置可以选择放置它的位置。但是,如果文件在重新加载时未在配置中更改。它倾向于使文件锁定并创建额外的文件EVERY重新加载

我想让这个工作。如果这开始正常工作。然后我可以在我的项目中正确实施它。

【问题讨论】:

  • 我的代码在这篇文章中看起来很乱。我将使用更简洁的代码更新帖子。确保它导致相同的问题。然后我会在研究出了什么问题后尝试查看最佳答案并发布更多相关信息。

标签: java file filehandle java.util.logging


【解决方案1】:

您正在创建多个文件,因为您正在创建一个 FileHandler 并且从不关闭它。

fh = new FileHandler(file.getPath(), append);
...
return new FileHandler(file.getPath(), append);

解决办法?

return fh;

最终与否完全没有区别。在这种情况下,您实际上确实希望在 catch 块中关闭,因为如果您不这样做,将无法关闭它。

【讨论】:

  • 那里一定是意外。这也是代码中的问题之一。
【解决方案2】:

总是关闭finally块内的资源-

try {
    fh = new FileHandler(file.getPath(), append);
    fh.setFormatter(new Formatter() {

    @Override
    public String format(LogRecord record) {
        return "[test] " + "[" + record.getLevel().toString() + "]" + String.format(record.getMessage(), record.getParameters()) + newline;
    }
    });
    return new FileHandler(file.getPath(), append);
} catch (Exception e) {

    return null;
    // never close in catch

} finally {
    //  lastly close anything that may be open
    if (fh != null){
        try {
            fh.close();
        } catch (Exception ex){
            // error closing   
        }
    }
}

【讨论】:

  • 当你返回一个对象时这将如何工作(本质上退出 try 语句)
  • @CoasterChris 这就是它的美妙之处。 try 中的 return 语句将存储处理程序,直到 finally 块完成然后返回。 finally 总是被执行,除非你当然关掉电脑。捕获也是如此。在返回null之前,finally会被执行然后返回null。
  • 杜塔我感谢你。我确实尝试了 try 块。 jvm现在让我感到困惑。但无论哪种方式,关闭声明都应该有效。您是否在代码中的其他地方看到过关闭语句?关于它如何不起作用的任何想法?
  • @CoasterChris 没问题..但是你怎么知道'close'语句没有被执行?能不能逐行调试看看?
  • 他们被处决了。但是文件锁仍然存在。我可以逐行调试。它说他们被处决了。正如它在流文档的 javadocs 中所述,它可能会默默地失败。编辑:忘了我正在阅读记录器removeHandler。 .close() 上可能不一样
【解决方案3】:

使用 log 方法后关闭所有处理程序。

    this.logger.log(Level.SEVERE, (exception.getClass().getName() + ": " + exception.getMessage()) + "\r\n" + exception.getCause() + "\r\n" + "\r\n");

    for (Handler handler : this.logger.getHandlers())
    {
        handler.close();
    }

【讨论】:

    【解决方案4】:

    好吧,这里有一个问题:

     try {
                fh = new FileHandler(file.getPath(), append);
                fh.setFormatter(new Formatter() {
    
                    @Override
                    public String format(LogRecord record) {
                        return "[test] " + "[" + record.getLevel().toString() + "]" + String.format(record.getMessage(), record.getParameters()) + newline;
                    }
                });
                return new FileHandler(file.getPath(), append);
            } catch (Exception e) {
                if (fh != null)
                    fh.close();
                return null;
    

    你永远不会在 try 语句中关闭文件,只有在出现错误时才会关闭它。您应该在完成后立即关闭文件:

     try {
                fh = new FileHandler(file.getPath(), append);
                fh.setFormatter(new Formatter() {
    
                    @Override
                    public String format(LogRecord record) {
                        return "[test] " + "[" + record.getLevel().toString() + "]" + String.format(record.getMessage(), record.getParameters()) + newline;
                    }
                });
                //close fh
                fh.close();
                return new FileHandler(file.getPath(), append);
            } catch (Exception e) {
                if (fh != null)
                    fh.close();
                return null;
    

    【讨论】:

    • 重新阅读您的代码。您创建了一个新的 fh FileHandler 用于返回。然后你关闭它并重新创建一个新的而不使用原来的?有意义吗?
    猜你喜欢
    • 2015-08-10
    • 2014-01-18
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多