Java解除文件占用即Dom4j操作后实现xml关流

作者:Erneste 时间:2022-07-05 19:18:35 

一、背景

项目中要解析xml,由于Dom4j的诸多优点,我就用Dom4j解析xml,代码如下:


public void readXML() {
   SAXReader reader = new SAXReader();
   Document doc = null;

try {
     doc = reader.read(new File("demo.xml"));
     Element root = doc.getRootElement();

/**
      * 其他代码
      */
   } catch (DocumentException e) {
     e.printStackTrace();
   }
}

查看Dom4j的api,你会发现,不管是SAXReader,还是Document,都没有提供关闭流资源的操作,我当时天真的以为Dom4j自动关闭流资源了,不用我们再关流了。

后来的某一天,由于业务的需要,需要在程序中删除此xml,我发现不管我用file.deleteOnExit(),还是用file.delete()。都删除不了此xml文件,显示文件被占用,无法删除,我自己用鼠标去删除,也是显示“操作无法完成 因为文件已在 Java™ Platform SE binary 中打开”,至此才发现Dom4j没有关闭流资源,Dom4j当时给我的是幻觉,幸好线上xml文件不是特别多,不然要出生产事故了。

二、原因

Dom4j解析完xml没有关闭连接。

三、解决方法

方法一、系统进行资源强制回收System.gc(),解除占用

但是System.gc()只是通知GC进行垃圾回收,但是啥时GC回收不知道,所以这个方法不一定一次成功,如果一次强制回收不成功,那就搞个循环,多来几次。


public boolean forceDelete(File file){
   boolean result=file.delete();
   if (!result) {
     System.gc();  //回收资源
     file.delete();
   }
   return result;
}

方法二、在Dom4j中关闭流资源

这里没有以内部类的方式创建InputStream,而是显示创建,然后关流(jdk1.7 try-with-resource语法)。


public void readXML() {
   SAXReader reader = new SAXReader();
   Document doc = null;

try(FileInputStream fin = new FileInputStream("demo.xml")) {
     doc = reader.read(fin);
     Element root = doc.getRootElement();

/**
      * 其他代码
      */
   } catch (DocumentException e) {
     e.printStackTrace();
   } catch (FileNotFoundException e) {
     e.printStackTrace();
   } catch (IOException e) {
     e.printStackTrace();
   }
 }

四、建议

1、创建IO流如果不是特别需要,一般尽量不要使用“匿名内部类”来创建;

2、使用IO流读取文件,记得要在最后把流关闭了,不然会一直占着文件不放开,并且耗费资源。而且谨记:先创建的流最后关闭,且创建关闭一一对应。

来源:https://www.cnblogs.com/DDgougou/p/11211294.html

标签:Java,Dom4j,xml,关流
0
投稿

猜你喜欢

  • Android自定义processor实现bindView功能的实例

    2023-09-07 17:16:37
  • 基于C#动手实现网络服务器Web Server

    2023-01-21 20:13:28
  • Android开发中关于获取当前Activity的一些思考

    2023-07-14 07:35:34
  • android仿音悦台页面交互效果实例代码

    2023-03-27 12:55:54
  • 快速入门介绍Java中强大的String.format()

    2022-10-28 15:53:49
  • C#中using关键字的使用方法示例

    2023-07-30 14:17:02
  • Android UI设计系列之自定义ListView仿QQ空间阻尼下拉刷新和渐变菜单栏效果(8)

    2023-05-23 14:57:04
  • string与stringbuilder两者的区别

    2021-11-26 00:01:06
  • c# 实现雪花分形的示例

    2023-05-10 02:59:56
  • Android Loader的使用以及手机通讯录的获取方法

    2023-12-22 02:10:05
  • SpringBoot自定义maven-plugin插件整合asm代码插桩

    2021-05-24 02:15:49
  • maven profile自动切换环境参数的2种方法详解

    2022-10-28 09:18:39
  • java 示例讲解循环语句的使用

    2021-12-17 06:23:01
  • C#纯技术之Class写入Json

    2023-01-15 17:13:49
  • Java Iterator迭代器_动力节点Java学院整理

    2022-11-08 13:50:39
  • Logback配置文件这么写,还说你不会整理日志?

    2022-10-30 10:23:09
  • C#使用log4net打日志

    2022-11-08 17:50:57
  • Java 动态数组的实现示例

    2022-02-27 07:05:25
  • Java中类的加载顺序执行结果

    2022-03-12 18:12:35
  • Android使用URL读取网络资源的方法

    2023-07-27 10:56:39
  • asp之家 软件编程 m.aspxhome.com