有关此目标背后的动机(以及我为实现该目标所做的努力)的更多详细信息,请查看我的上一个问题。我决定完全以一个新问题提出这个问题,因为我认为它已经发展到足以值得这样做了。作为总结,我打算将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库之后,我真的很难找到甚至关闭了通道,更不用说如何防止通道关闭了。任何指针都很棒!谢谢。
一种干净的方法是创建一个FilterInputStream并覆盖close不执行任何操作:
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(); } }