Prevent closing the file after reading the xml file

For more information on the motivation for this goal (and my attempts to solve it), review the previous question. I decided to ask this as a new question in its entirety, as I thought it had developed enough to deserve it. As a summary, I intend to use JDOM in combination with NIO to:

  • Get an exclusive file lock in an XML file.
  • Read the file in Document.
  • Arbitrary changes (with the lock still active!).
  • Write the changes to the xml file.
  • Release the file lock.

However, the problem I get is that the inline code to read the XML file into the document object closes the pipe (and therefore releases the lock), as shown below:

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();
    }
}

Conclusion:

true
false

Java-, , , , . ! .

+1
2

- 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();
    }
}
+3

try-with-ressource statment? , , , , ( ( ), try)

try (final Channel channel = new RandomAccessFile(new File(path), "rw").getChannel()) {
  // your stuff here
} catch (IOException ex) {
  ex.printStackTrace();
}
-1

Source: https://habr.com/ru/post/1695893/


All Articles