0

I am trying to parse a xml file using DocumentBuilderFactory
The parsing is going well but the problem is that DocumentBuilderFactory close the underlying stream when calling parse method which i don't want because i need to process the stream further

I create a wrapper class in order to prevent the closure of the inputstream but it still closes it nevertheless

Any advice please ?

There is my wrapper class

import java.io.IOException;
import java.io.InputStream;

public class UncloseableInputStream extends InputStream  {

    private final InputStream input;
    
     private boolean canBeClosed = false;
     
    public UncloseableInputStream(InputStream input) {
         this.input = input;
    }

    @Override
    public void close() throws IOException {    
        if(canBeClosed) {
            super.close();
        }
    }
    
    @Override
    public int read() throws IOException {
      return input.read();
    }

    public void allowToBeClosed() { 
        canBeClosed = true; 
    }
}

The sample DocumentBuilderFactory parsing code

        builderFactory = DocumentBuilderFactory.newInstance();
        builder = builderFactory.newDocumentBuilder();
        try {
            //NOT EMPTY
            byte[] bytesFile = batchFileUtils.fileToByteArray(inputStream);
            System.out.println("ok");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        xmlDocument = builder.parse(new UncloseableInputStream(inputStream));
        try {
            //EMPTY
            byte[] bytesFile = batchFileUtils.fileToByteArray(inputStream);
            System.out.println("ok");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

Thank you very much

ulquiorra
  • 931
  • 4
  • 19
  • 39
  • So if you need to parse the stream further wouldn't it make more sense to make use of the document already parsed? Like reuse the `xmlDocument`? If using the document is not an option you could just copy the stream before passing it to the parser... and depending on your implementation you could even do both async – Jorge Campos Oct 01 '21 at 23:38
  • @JorgeCampos Thank you for your answer. The second usage is completely different from the parsing of the document. it's about building a zipfile . The parsing of the document is only needed for retrieving some value. By copy of the stream , you mean clone it ? – ulquiorra Oct 01 '21 at 23:43
  • 1
    If you are referring to java clone then no. You need to actually duplicate your stream into a new one see a reference here: https://stackoverflow.com/a/5924132/460557 – Jorge Campos Oct 01 '21 at 23:46
  • The reuse is still possible because you can generate a new stream from it to do the zipping :) – Jorge Campos Oct 01 '21 at 23:48
  • @JorgeCampos Thank you very much , it works ! Can you please make an answer ? I will mark it as accepted . – ulquiorra Oct 04 '21 at 09:02

1 Answers1

1

As discussed in the comments section a solution for this particular request is to duplicate the current inputStream object and use the new one for the second use case.

Adding it as an answer as requested.

Jorge Campos
  • 22,647
  • 7
  • 56
  • 87