javafile-ioinputstream

Exception stating " Resetting to invalid mark " comes while marking an inputStream and resetting it, for Large files.?


I am using InputStream object to calculate Md5 of some file. I mark the stream Later I reset the stream. However for large files the following exception comes...

inStreamLatestFile.mark(0);
checkSumCalculated = MD5CheckSumCalculator.calculateMD5CheckSum(inStreamLatestFile);
inStreamLatestFile.reset();

The exception

.Md5ValidationAggrStrat ||**Error in calculating checksum:: java.io.IOException: Resetting to invalid mark**
                        ||java.io.IOException: Resetting to invalid mark
                        ||at java.io.BufferedInputStream.reset(BufferedInputStream.java:437)
                        ||at com.amadeus.apt.ib.modules.func.map.camel.strategy.Md5ValidationAggrStrategy.aggregate(Md5ValidationAggrStrategy.java:81)
                        ||at org.apache.camel.processor.aggregate.AggregateProcessor.onAggregation(AggregateProcessor.java:365)
                        ||at org.apache.camel.processor.aggregate.AggregateProcessor.doAggregation(AggregateProcessor.java:245)
                        ||at org.apache.camel.processor.aggregate.AggregateProcessor.process(AggregateProcessor.java:201)
                        ||at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
                        ||at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)

I have tried closing the stream and reopening it this way.. just to get some exceptions as follows::

 try {
        inStreamLatestFile= ExchangeHelper.getMandatoryInBody(
                  oldExchange, InputStream.class);

        //inStreamLatestFile.mark(0);
        checkSumCalculated = MD5CheckSumCalculator.calculateMD5CheckSum(inStreamLatestFile);

        //closing the inputStream of the latest file
        if(inStreamLatestFile != null){
            try {
                inStreamLatestFile.close();
            } catch (IOException e) {
                logger.error("Error occurred in closing the stream :: "+ e.getMessage());
            }
        }


        tempInputStream= ExchangeHelper.getMandatoryInBody(
                  oldExchange, InputStream.class);
        oldExchange.getIn().setBody(tempInputStream);

However the following exception comes when I try to resuse the newly retrived InputStream.

 caught: java.io.IOException: Stream closed: java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:162)

Solution

  • I'm going to assume you are using a BufferedInputStream because its source code for reset() method is

    public synchronized void reset() throws IOException {
        getBufIfOpen(); // Cause exception if closed
        if (markpos < 0)
            throw new IOException("Resetting to invalid mark"); // exception you are getting
        pos = markpos;
    }
    

    The following call

    MD5CheckSumCalculator.calculateMD5CheckSum(inStreamLatestFile);
    

    must be doing something to the markPos.

    If you have no control over it, just reopen the stream. If you can't reopen the stream, ie. you're retrieving the same instance every time, consider using a ByteArrayOutputStream

    You can read the original InputStream into a ByteArrayOutputStream. Copy the bytes in that stream into a new ByteArrayInputStream. Pass that to the MD5 calculator. Then create a new ByteArrayInputStream again with the same bytes and pass that to whatever else you need.