有关这个目标背后的动机(以及我解决它的努力)的更详细信息,请查看我的前一个问题。我决定把这个问题作为一个全新的问题来提出,因为我认为它已经发展到值得这样做的程度了。总之,我打算结合使用JDOM和NIO,以便:
Document对象。但是,我遇到的问题是,将xml文件读入文档对象的内置代码关闭通道(因此释放锁),如下所示:
import java.io.*;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import javax.xml.parsers.*;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class Test4{
String path = "Test 2.xml";
private DocumentBuilderFactory dbFactory;
private DocumentBuilder dBuilder;
private Document doc;
public Test4(){
try (final FileChannel channel = new RandomAccessFile(new File(path), "rw").getChannel()) {
dbFactory = DocumentBuilderFactory.newInstance();
dBuilder = dbFactory.newDocumentBuilder();
System.out.println(channel.isOpen());
doc = dBuilder.parse(Channels.newInputStream(channel));
System.out.println(channel.isOpen());
channel.close();
} catch (IOException | ParserConfigurationException | SAXException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new Test4();
}
}输出:
true
false在浏览了文档并拖曳了Java库中的构建之后,我甚至很难找到通道关闭的地方,更不用说如何防止它关闭了。任何指示都是很棒的!谢谢。
发布于 2014-10-28 10:44:15
要做到这一点,一个简单的方法是创建一个FilterInputStream并覆盖close以不做任何操作:
public Test() {
try {
channel = new RandomAccessFile(new File(path), "rw").getChannel();
dbFactory = DocumentBuilderFactory.newInstance();
dBuilder = dbFactory.newDocumentBuilder();
System.out.println(channel.isOpen());
NonClosingInputStream ncis = new NonClosingInputStream(Channels.newInputStream(channel));
doc = dBuilder.parse(ncis);
System.out.println(channel.isOpen());
// Closes here.
ncis.reallyClose();
channel.close(); //Redundant
} catch (IOException | ParserConfigurationException | SAXException e) {
e.printStackTrace();
}
}
class NonClosingInputStream extends FilterInputStream {
public NonClosingInputStream(InputStream it) {
super(it);
}
@Override
public void close() throws IOException {
// Do nothing.
}
public void reallyClose() throws IOException {
// Actually close.
in.close();
}
}发布于 2014-10-28 10:20:22
你试过试着用资源状态了吗?尽管如此,这并不是这个特性的主要目的,也许它可以实现您所寻找的功能(以自动关闭重新源(您的通道)的形式),但只有在您离开相应的try-块时才会这样做。
try (final Channel channel = new RandomAccessFile(new File(path), "rw").getChannel()) {
// your stuff here
} catch (IOException ex) {
ex.printStackTrace();
}https://stackoverflow.com/questions/26605671
复制相似问题