如何跟踪 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;
}
}
我正在使用 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;
}
}