java怎么解除文件占用(Dom4j操作完xml后怎么關流)


 

一、背景

  項目中要解析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流讀取文件,記得要在最后把流關閉了,不然會一直占着文件不放開,並且耗費資源。而且謹記:先創建的流最后關閉,且創建關閉一一對應。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM