有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

读取大文件时java StAX解析器的xml问题

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

while (eventReader.hasNext()) { }

我尝试在同一个文件上使用SAX解析器来读取标记。它非常快,在几秒钟内完成

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


共 (2) 个答案

  1. # 1 楼答案

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

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

  2. # 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解析器的情况下,当客户端应用程序需要与XML信息集交互时,它会调用XML解析库中的方法,也就是说,客户端只有在显式请求时才获取(拉取)XML数据。但是在SAX解析器的情况下,当解析器遇到XML信息集中的元素时,XML解析器会向客户端发送(推送)XML数据,也就是说,无论客户端当时是否准备好使用数据,解析器都会发送数据。 StAX API可以读写XML文档。使用SAXAPI,只能读取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();
                }
    
            }
        }