最近翻阅之前代码笔记的时候,发现有1个关于IO关闭
的问题可以分享给大家。
大概的业务逻辑是:解析XML
后,然后将其移动到另外一个目录备份。
业务很简单,处理正常的XML
也是没有问题的,但是测试时候发现,一旦XML
解析出现问题,文件无法移动或者删除。
这到底是什么原因造成的了?
简单的代码原型如下所示:
public static void main(String[] args) throws DocumentException {
SAXReader saxReader = new SAXReader();
File file=new File(" /Users/liuchunfu/GitProject/test.xml");
Document read = saxReader.read(file);
//todo something
boolean delete = file.delete();
System.out.println(delete);
}
请注意第4句代码:
Document read = saxReader.read(file);
当test.xml
正常的时候,文件肯定能正常删除。
一旦test.xml
解析出问题,文件无法删除。
为什么会出现这个问题?
经过查看dom4j
的源码,可以看到它的处理方式为:
public Document read(File file) throws DocumentException {
try {
InputSource source = new InputSource(new FileInputStream(file));
if (this.encoding != null) {
source.setEncoding(this.encoding);
}
String path = file.getAbsolutePath();
//.....
}
}
请注意它的第3句代码:
InputSource source = new InputSource(new FileInputStream(file));
大家看出一点什么问题来没?
new FileInputStream(file)
根本没有关闭?
这个也算它的一个 bug吧,应该在内部将流关闭才好。
public static void main(String[] args) throws DocumentException, FileNotFoundException {
SAXReader saxReader = new SAXReader();
File file=new File(" /Users/liuchunfu/GitProject/test.xml");
try (FileInputStream fis=new FileInputStream(file)){
//传入流
Document read = saxReader.read(fis);
//todo ....
} catch (Exception e) {
e.printStackTrace();
}
file.delete();
}
其实dom4j
给我们提供了丰富的 API
其中就有直接传入 流的操作。
当我们使用第三方API
的时候,一定要自己留一个心眼,将更多的东西掌握到自己的手里,避免问题发生。
将文件交给第三方 API去进行处理的时候,建议最好自己控制流的关闭。
利用 JDK7 的 try-with-resources 很方便的控制流的操作。