如何为 java.util.logging.FileHandler 使用 try-with-resources?

Posted

技术标签:

【中文标题】如何为 java.util.logging.FileHandler 使用 try-with-resources?【英文标题】:How to use try-with-resources for java.util.logging.FileHandler? 【发布时间】: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 【参考方案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 上面的场景。

以上是关于如何为 java.util.logging.FileHandler 使用 try-with-resources?的主要内容,如果未能解决你的问题,请参考以下文章

如何为下拉菜单制作 CSS 边框?

如何为 CAShapeLayer 路径和填充颜色设置动画

iPhone - 如何为图像着色?

如何为 RecyclerView 设置 onItemClickListener? [复制]

WCF - 如何为 NTLM 身份验证配置 netTcpBinding?

如何为 UIToolbar 上的按钮添加滚动?