如何在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文件中的整体进度? 从读取器获取偏移量适用于较小的文件:

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

但作为整数偏移,它可能只适用于高达2GB的文件…

一个简单的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; } } 

似乎Stax API无法为您提供long偏移。

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

您可以将此阅读器传递给XMLInputFactory 。 然后,处理程序循环可以直接从阅读器获取偏移信息。

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