Java 防止读取xml文件后关闭文件通道
有关此目标背后动机(以及我为解决此目标所做的努力)的更多详细信息,请查看我的。我决定把这个问题作为一个全新的问题提出,因为我认为它已经发展到值得这样做的程度。作为总结,我打算将JDOM与NIO结合使用,以便:Java 防止读取xml文件后关闭文件通道,java,xml,concurrency,io,channel,Java,Xml,Concurrency,Io,Channel,有关此目标背后动机(以及我为解决此目标所做的努力)的更多详细信息,请查看我的。我决定把这个问题作为一个全新的问题提出,因为我认为它已经发展到值得这样做的程度。作为总结,我打算将JDOM与NIO结合使用,以便: 获取xml文件的独占文件锁定 将文件读入文档对象 进行任意更改(锁定仍处于活动状态!) 将更改写回xml文件 释放文件锁 但是,我遇到的问题是,将xml文件读入文档对象的内置代码会关闭通道(从而释放锁),如下所示: import java.io.*; import java.nio.cha
文档
对象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库之后,我真的很难找到通道关闭的位置,更不用说如何防止它关闭了。任何指针都会很棒!谢谢。你试过这个座位了吗?尽管这并不是此功能的主要目的,但这可能正是您想要的(以自动关闭资源(您的频道)的形式,但仅当您离开相应的try块时)
一种干净的方法是创建一个
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();
}
}
你好,谢谢你的回复。不幸的是,我只是尝试了一下,但效果似乎不大。虽然看起来有点干净,但我还是会保留它的!这将关闭通道。这正是他想要阻止的。一定要读这个问题。@EJP我知道结束了(一定要读我的答案),我只是想在调用
dBuilder.parse()
后保留锁,这是OP需要的。请务必阅读此问题。DocumentBuilder.parse()
正在关闭提供的输入流。很抱歉,此问题有点误导,我的意思是我无法确定内置DocumentBuilder类在何处关闭通道以覆盖该行为。不过,覆盖FilterInputStream
的默认关闭行为(与接受的答案一样)似乎可以获得相同的结果。
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();
}
}