Java 对于大文件,在标记 inputStream 并重置它时出现“重置为无效标记”的异常。?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18573767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 09:07:31  来源:igfitidea点击:

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

javafile-ioinputstream

提问by Kumar Ritesh

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

我正在使用 InputStream 对象来计算某个文件的 Md5。我标记了流 后来我重置了流。但是,对于大文件,会出现以下异常...

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.

但是,当我尝试重用新检索的 InputStream 时,会出现以下异常。

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

采纳答案by Sotirios Delimanolis

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

我将假设您正在使用 aBufferedInputStream因为它的reset()方法源代码是

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.

一定是对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

如果您无法控制它,只需重新打开流。如果您无法重新打开流,即。您每次都检索相同的实例,请考虑使用ByteArrayOutputStream

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

您可以将原件读InputStreamByteArrayOutputStream. 将该流中的字节复制到新的ByteArrayInputStream. 将其传递给 MD5 计算器。然后ByteArrayInputStream使用相同的字节再次创建一个新的并将其传递给您需要的任何其他内容。