我有2个BufferedInputStreams,它们都包含一个xml字符串:一个小字符串,一个非常大。
以下是每个xml字符串的开头如何:
<RootElement success="true">
我创建了一个方法:
我的印象是,缓冲输入流的缓冲区(默认为8012bytes)和标记readlimit的大小实际上都很重要,因为我只是在重置之前读取前50个字节而不管如何我的输入流很大。
不幸的是,我得到了一个&#34; IOException: resseting to invalid mark
&#34;例外。这是相关代码:
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个字节!还有哪些因素可能导致这种行为?
答案 0 :(得分:1)
根据InputStream类的文档 - reset()方法:
public void reset() 抛出IOException
重置的一般合同是: 如果方法markSupported返回true,则: 如果自标记以来从流中读取的字节数 最后一次调用大于最后一次调用时标记的参数, 然后可能抛出IOException。
在您的代码中,
您已将100作为字节读取限制。
responseStream.mark(100);
并且代码部分的可能性非常高:
xmlReader.next();
读取超过100个字节,标记失效并调用reset()方法抛出IOException。
XMLStreamReader.next():
获取下一个解析事件 - 处理器可以返回所有连续的 单个块中的字符数据,或者可以将其拆分为多个 块
因此,读者可以保持读取超过读取限制字节的数量,从而导致标记无效。 (无论文件大小如何,以及连续字符是否很大,都会发生这种情况。)
第二个例子,
如果方法markSupported返回false,则: 对reset的调用可能会抛出IOException
但BufferedInputStream支持标记
public boolean markSupported()
测试此输入流是否支持mark和reset方法。该 bufferedInputStream的markSupported方法返回true。
所以第二种情况可以减少。
答案 1 :(得分:0)
这是一个猜测,但XMLStreamReader
可能会在InputStream
或getAttributeCount
方法中读取getAttributeLocalName
的很大一部分,尽管它可能正在完成当创建XMLStreamReader时......
我没有通过OpenJDK代码来确认这一点。