java - BufferedInputStream 标记/重置无效标记

标签 java bufferedinputstream

我有 2 个 BufferedInputStream,它们都包含一个 xml 字符串:一个很小,一个很大。

以下是每个 xml 字符串的开头:

<RootElement success="true">

我创建了一个方法:

  1. 在输入流的开头设置标记
  2. 读取 xml 的前几个字节以检查根元素是否具有特定属性。
  3. 将输入流重置到标记位置,以便另一种方法可以享受完整的完整流。

我的印象是,缓冲输入流的缓冲区大小(默认为 8012 字节)和标记读取限制实际上都不重要,因为无论我的大小有多大,我只在重置之前读取前 50 个字节。输入流是。

不幸的是,我收到“IOException:重新设置为无效标记”异常。相关代码如下:

private boolean checkXMLForSuccess(BufferedInputStream responseStream) throws XMLStreamException, FactoryConfigurationError
{
    //Normally, this should be set to the amount of bytes that can be read before invalidating.
    //the mark. Because we use a default buffer size (1024 or 2048 bytes) that is much greater
    //than the amount of bytes we will read here (less than 100 bytes) this is not a concern.
    responseStream.mark(100);

    XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(responseStream);
    xmlReader.next(); //Go to the root element

    //This is for loop, but the root element can only have 1 attribute.
    for (int i=0; i < xmlReader.getAttributeCount(); i++)
    {
        if(xmlReader.getAttributeLocalName(i).equals(SUCCES_ATTRIBUTE))
        {
            Boolean isSuccess = Boolean.parseBoolean(xmlReader.getAttributeValue(i));

            if (isSuccess)
            {
                try
                {
                    responseStream.reset();
                }
                catch (IOException e)
                {
                    //Oh oh... reset mark problem??
                }

                return true; 
            }
        }
    }

    return false;
}

现在,我当然尝试将标记读取限制设置为更高的数字。我必须将其设置为 10000 才最终起作用。我无法想象下面的代码需要读取 10000 个字节!还有哪些其他因素可能导致此行为?

最佳答案

根据InputStream类的文档-reset()方法:

public void reset() throws IOException

The general contract of reset is: If the method markSupported returns true, then: If the number of bytes read from the stream since mark was last called is larger than the argument to mark at that last call, then an IOException might be thrown.

在您的代码中,

您的字节读取限制已超过 100。

responseStream.mark(100);

并且代码部分很有可能是:

xmlReader.next();

读取超过 100 个字节,标记失效,调用 reset() 方法抛出 IOException。

XMLStreamReader.next():

Get next parsing event - a processor may return all contiguous character data in a single chunk, or it may split it into several chunks

因此,读取器可能会继续读取超过读取限制的字节,从而导致标记无效。 (无论文件大小如何,并且连续字符是否很大,都会发生这种情况)。

第二个实例,

If the method markSupported returns false, then: The call to reset may throw an IOException

但是BufferedInputStream支持标记,

public boolean markSupported()

Tests if this input stream supports the mark and reset methods. The markSupported method of BufferedInputStream returns true.

所以第二种情况可以删掉。

关于java - BufferedInputStream 标记/重置无效标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25669118/

相关文章:

java - 如何修复此 Try-With-Resources block 中出现的 "SQLServerException: The connection is closed."问题?

java - 我如何从缓冲读取器输入字符串?

Java Android : BufferedInputStream to byte Array

java - JavaFX 2 中的组合框键值对

java - 使用控制台界面搜索数组

java - 如何读取 BufferedInputStream 中的一行?

android - 将 BufferedInputStream 转换为文件

java - 如何访问 Android 中 Web API 方法的返回值?

java - 在循环中的 ArrayList.add() 之后,所有元素都是相同的。为什么?

java - 插入场景中按版本划分的 JPA/Hibernate 乐观锁