如何跟踪 StAX 中大文件的解析进度?

How do I keep track of parsing progress of large files in StAX?

我正在使用 StAX API 处理大型 (1TB) XML 文件。假设我们有一个循环处理一些元素:

XMLInputFactory fac = XMLInputFactory.newInstance();
 XMLStreamReader reader = fac.createXMLStreamReader(new FileReader(inputFile));
   while (true) {
       if (reader.nextTag() == XMLStreamConstants.START_ELEMENT){
            // handle contents
       }
}

如何在大型 XML 文件中跟踪总体进度?从 reader 获取偏移量适用于较小的文件:

int offset = reader.getLocation().getCharacterOffset();

但作为一个整数偏移量,它可能只适用于最大 2GB 的文件...

似乎 Stax API 不能给你一个 long 偏移量。

作为解决方法,您可以创建一个自定义 java.io.FilterReader class 来覆盖 read()read(char[] cbuf, int off, int len) 以增加 long 偏移量。

您会将此 reader 传递给 XMLInputFactory。 然后处理程序循环可以直接从 reader.

中获取偏移量信息

您也可以使用 FilterInputStream 在 byte-level 读数上执行此操作,计算字节偏移量而不是字符偏移量。这将允许在给定文件大小的情况下进行准确的进度计算。

一个简单的 FilterReader 应该可以。

class ProgressCounter extends FilterReader {
    long progress = 0;

    @Override
    public long skip(long n) throws IOException {
        progress += n;
        return super.skip(n);
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        int red = super.read(cbuf, off, len);
        progress += red;
        return red;
    }

    @Override
    public int read() throws IOException {
        int red = super.read();
        progress += red;
        return red;
    }

    public ProgressCounter(Reader in) {
        super(in);
    }

    public long getProgress () {
        return progress;
    }
}