2014-09-04 106 views
2

我有2个BufferedInputStreams,它们都包含一个xml字符串:一个小字符串和一个非常大的字符串。BufferedInputStream标记/重置无效标记

这里的每个XML字符串的开始看起来像:

<RootElement success="true"> 

我创建了一个方法:

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

我的印象是,缓冲输入流的缓冲区大小(默认值为8012bytes)和标记读取限制的大小实际上很重要,因为我只是在重置前像前50个字节一样读取,而不管我的输入流有多大。

不幸的是我得到一个“IOException: resseting to invalid mark”异常。这里是相关的代码:

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

这是一个猜测,但XMLStreamReader很可能读getAttributeCountgetAttributeLocalName方法在InputStream的很大一部分,虽然它可能是在创建的XMLStreamReader当它正在做......

我的天堂”但是通过OpenJDK代码查看来确认这一点。

1

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

公共无效复位() 抛出IOException异常

复位的一般合同是: 如果该方法的markSupported返回true,那么: 如果自上次调用标记为 以来从流中读取的字节数大于最后一次调用标记的参数 ,则可能会抛出IOException。

在你的代码,

您已通过100字节读取限制。

responseStream.mark(100); 

并有一个非常高的概率的代码的一部分:

xmlReader.next(); 

读取多于100个字节,并且被无效的标记,并复位()方法的调用抛出一个IOException 。

XMLStreamReader.next():

获取下一个解析事件 - 一个处理器可返回所有连续 字符数据用单个存储块,或者它可以将其分割成数块

因此,读者可能会一直读取超过读取限制字节的数据,导致标记失效。 (不管文件大小如何,连续字符都很大)。

二审,

如果该方法的markSupported返回false,那么: 呼叫重置可能抛出IOException

不过的BufferedInputStream支持标记,

公众布尔值markSupported()

测试此输入流是否支持标记和重置方法。 BufferedInputStream的markSupported方法的 返回true。

所以第二种情况可以减少。

+0

如果xmlReader.next()读取的字节数超过100个字节,为什么500字节的小XML文件可以工作,但大小为5000的xml文件不起作用?都具有相同的根元素,并具有相同的属性,并且都大于100个字节。 – user1884155 2014-09-04 15:46:56

+0

@ user1884155在这一点上,没有真正查看XMLReader在OpenJDK代码中做了什么,这都是猜测。 – Powerlord 2014-09-04 15:56:37

+0

@ user1884155,@ Powerlord - 已更新我的回复与您的意见 – BatScream 2014-09-04 15:57:35