【问题标题】:Issue with java StAX parser when reading a large file读取大文件时 java StAX 解析器出现问题
【发布时间】:2018-02-13 05:46:36
【问题描述】:

我正在尝试使用具有近 180k 行的 StAX 解析器读取 XML 文件。 核心逻辑在数据结构中查找某些标签、属性和存储。 对于这种类型的大文件,StAX 解析器需要花费大量时间。 在没有任何核心逻辑的情况下,它需要将近 15 分钟,只是在 while 循环上进行迭代。

while (eventReader.hasNext()) { }

我在同一个文件上尝试了 SAX 解析器来读取标签。速度非常快,几秒钟内即可完成。

StAX 解析器会出现什么问题? 请推荐任何适用于大文件并在内存和空间利用率方面表现良好的 XML 解析器。 ?

【问题讨论】:

    标签: java xml parsing sax stax


    【解决方案1】:

    调用hasNext() 将始终返回true,除非您已到达输入的末尾,并且您的代码不会更改输入中的位置,因为它从不读取任何数据。您需要在循环中调用next(),然后最终hasNext() 将返回false。

    顺便说一句,按照现代标准,180k 行并不是一个大文件。

    【讨论】:

      【解决方案2】:

      坚持使用 StAX 解析器,因为 SAX 和 Stax 都遵循流式编程模型来解析 XML 我运行了 SAX 和 StAX 的示例代码,结果如下

      SAX 解析器: 总时间:10.73 毫秒 最大内存:1842688 分配的内存:125952 空闲内存:107293

      StAX 解析器: 总时间:7.5 毫秒 最大内存:1842688 分配的内存:125952 空闲内存:120611

      StAX 是一个 PULL API,而 SAX 是一个 PUSH API,这意味着在 StAx Parser 的情况下,客户端应用程序在需要与 XML 信息集交互时调用 XML 解析库上的方法——也就是说,客户端只获取 (拉)XML 数据,当它明确要求它。但在 SAX 解析器的情况下,当解析器遇到 XML 信息集中的元素时,XML 解析器发送(推送)XML 数据到客户端——也就是说,解析器发送数据是否或者当时客户是否准备好使用它。 StAX API 可以读取和写入 XML 文档。使用 SAX API,只能读取 XML 文件。

      StAX 代码:

      public static void main(String[] args) throws FileNotFoundException, XMLStreamException {
              XMLInputFactory xf=XMLInputFactory.newInstance();
              XMLStreamReader xsr=xf.createXMLStreamReader(new InputStreamReader(new FileInputStream("C:\\Users\\RNayyar\\Desktop\\Context\\processedFiles\\post.xml")));
              String startElement = null;
              String endElement  =null;
              String elementTxt = null;
              SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
      
              while (xsr.hasNext()) {
                  int e = xsr.next();
                  if(e==XMLStreamConstants.START_ELEMENT){
                      //System.out.println("StartElement Name :" + xsr.getLocalName());
                      startElement = xsr.getLocalName();
                  }
                  if(e==XMLStreamConstants.END_ELEMENT){
                      //System.out.println("EndElement Name :" + xsr.getLocalName());
                      endElement = xsr.getLocalName();
                      if(startElement.equalsIgnoreCase(endElement))
                      System.out.println(" ElementName : "+ startElement + " ElementText : " + elementTxt);
                  }
                  if(e==XMLStreamConstants.CHARACTERS){
                      //System.out.println("Element TextValue :" + xsr.getText());
                      elementTxt = (xsr.getText().contains("\n")) ? "" : xsr.getText();
                  }
      
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-29
        • 1970-01-01
        • 1970-01-01
        • 2023-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多