【问题标题】:How to use try-with-resources for java.util.logging.FileHandler?如何为 java.util.logging.FileHandler 使用 try-with-resources?
【发布时间】:2020-06-05 06:35:06
【问题描述】:

我有以下代码并使用java.util.logging.FileHandler 创建日志文件。

在这种情况下,我应该手动关闭 finally 块中的资源。

try {
fh = new FileHandler("Test.log");
logger.addHandler(fh);
...
} catch (IOException e) {
e.printStackTrace();
} finally {
  if(fh!=null) { fh.close() };
}

此代码有效。现在,我认为它可以实现Autocloseable 接口。因此,我决定将try-with-resources 用于FileHandler,以便自动关闭资源(以消除手动关闭资源的工作)。

我试过的代码如下:

try(fh = new FileHandler("Test.log")) {
logger.addHandler(fh);
...
} catch (IOException e) {
e.printStackTrace();
}

但是这段代码不起作用。

它给出一个错误说:

The resource type FileHandler does not implement java.lang.AutoCloseable'

  • 如果可能,如何使用 try-with-resources 自动关闭文件处理程序?

  • 我需要手动关闭吗?或者我可以采取任何其他方法。

【问题讨论】:

  • 这没有意义。您需要处理程序保持打开状态。
  • 为什么要将FileHandler 添加到记录器,然后关闭它?它没有实现AutoClosable,因为它不应该那样使用。
  • 那你为什么不通过配置文件来做呢?
  • @AnishB。哦,是的。请参阅Javadoc
  • 只是为了记录,实际上有一个增强请求让Handler实现AutoCloseable - 所以可能有这样的用例:bugs.openjdk.java.net/browse/JDK-8025709

标签: java try-with-resources autocloseable


【解决方案1】:

首先,FileHandler 类没有实现AutoCloseable 接口。

因此,您不能在 FileHandler 上使用 try-with-resources

因此,您必须显式调用close() 方法。

所以,你必须采用你采取的第一种方法。

public class Example {

    private static Logger logger = Logger.getLogger("...");

    public static void main(String[] args) {
        FileHandler fh = null;
        try {
            fh = new FileHandler("Test.log");
            logger.addHandler(fh);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fh != null) {
                fh.close();
            }
        }
    }

}

您可以尝试创建自己的自定义Filehandler 类并在其中实现AutoCloseable 接口。

例如:

class CustomFileHandler implements AutoCloseable {

    private FileHandler fileHandler;

    public CustomFileHandler(FileHandler fileHandler) {
        this.setFileHandler(fileHandler);
    }

    @Override
    public void close() throws Exception {
        if (fileHandler != null) {
            fileHandler.close();
        }
    }

    public FileHandler getFileHandler() {
        return fileHandler;
    }

    private void setFileHandler(FileHandler fileHandler) {
        this.fileHandler = fileHandler;
    }

}

public class Example {

  private static Logger logger = Logger.getLogger("...");

  public static void main(String[] args) {
    try (CustomFileHandler fh = new CustomFileHandler(new FileHandler("Test.log"))) {
        logger.addHandler(fh.getFileHandler());
        ........
    } catch (Exception e) {
        e.printStackTrace();
    } 
  }

}

【讨论】:

  • @bharathiraja 现在,可以吗?
  • 这个答案,在向 OP 展示如何避免编译器错误的同时,是一个非常糟糕的主意。关闭日志处理程序而不将其从日志框架中删除意味着你'我们刚刚将日志框架置于不确定状态。随后的日志消息可能会被丢弃,或者可能导致应用程序异常。
  • 1. Autocloseable 不是一个类,而是一个接口。 2. OP的问题毫无意义,您甚至都没有发现,更不用说解决了。此代码将执行,但不会完成任何有用的操作。
  • @All,因为我已经解释了我在 cmets 中需要什么。我没有使用 FileHandler 记录应用程序日志。我的方案是在发生任何异常或任何验证失败时记录特定信息。比如说我有一个 csv,我正在读取并检查文件是有效格式还是有效文件名。如果文件名无效,那么我应该写文件名无效。以及每个生成日志的 csv 文件。示例 test.csv 将具有 test.log,并且所需的异常详细信息将在文件中。对于应用程序日志,我配置了 log4j2,这将包含所有应用程序特定的日志。
  • @All 你还觉得吗,我不应该用java.util.logging.FileHandler.for 上面的场景。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
相关资源
最近更新 更多