Search code examples
javainputstream

how to prevent DocumentBuilderFactory close underlying inputstream


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


Solution

  • 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.