【问题标题】:How to getProgress of large files using XMLStreamReader如何使用 XMLStreamReader 获取大文件的进度
【发布时间】:2016-06-10 14:30:01
【问题描述】:

我正在使用以下代码使用 XMLStreamReader 在 hadoop RecordReader 中读取大型 xml 文件(以 GB 为单位)

public class RecordReader {
   int progressCouunt = 0;
   public RecordReader() {
    XMLInputFactory factory = XMLInputFactory.newInstance();
    FSDataInputStream fdDataInputStream = fs.open(file); //hdfs file
    try {
          reader = factory.createXMLStreamReader(fdDataInputStream);
    } catch (XMLStreamException exception) {
           throw new RuntimeException("XMLStreamException exception : ", exception);
    }
   }
   @Override
  public float getProgress() throws IOException, InterruptedException {
     return progressCouunt; 
   }
}

我的问题是如何使用 XMLStreamReader 获取文件的读取进度,因为它不提供任何开始或结束位置来计算进度百分比。 我参考了How do I keep track of parsing progress of large files in StAX?,但不能使用filterReader。 请在这里帮助我。

【问题讨论】:

  • 你知道流的全长吗?
  • 不,使用 stax 是不可能的,因为它使用拉流,因此无法获得整个文件大小。
  • 我的意思是,来自其他地方。因为如果您无法确定数据的总长度在开始流式传输之前,您就无法跟踪进度。

标签: java xmlstreamreader


【解决方案1】:

您可以通过扩展 FilterInputStream 来包装 InputStream

public interface InputStreamListener {
    void onBytesRead(long totalBytes);
}

public class PublishingInputStream extends FilterInputStream {
    private final InputStreamListener;
    private long totalBytes = 0;

    public PublishingInputStream(InputStream in, InputStreamListener listener) {
       super(in);
       this.listener = listener;
    }

    @Override
    public int read(byte[] b) {
       int count = super.read(b);
       this.totalBytes += count;
       this.listener.onBytesRead(totalBytes);
    }

    // TODO: override the other read() methods
}

用法

XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream in = fs.open(file);
final long fileSize = someHadoopService.getFileLength(file);
InputStremListener listener = new InputStreamListener() {
    public void onBytesRead(long totalBytes) {
        System.out.println(String.format("Read %s of %s bytes", totalBytes, fileSize));
    }
};
InputStream publishingIn = new PublishingInputStream(in, listener);
try {
    reader = factory.createXMLStreamReader(publishingIn);
    // etc

【讨论】:

  • 实际上我正在使用 org.apache.hadoop.mapreduce.RecordReader 并且需要读取其中的进度。你能帮帮我吗?
  • 所以,更新自定义InputStreamListener 中的进度。要获得百分比,您需要知道总字节数。 InputStream.available() 不保证返回总字节数(它返回可以在没有阻塞的情况下读取的总数)。但是你可能会发现这个方法有效(取决于 InputStream 的实现)
  • 我尝试过使用 .available() 方法,但这里的总读取字节数和可用字节数始终相同。
猜你喜欢
  • 2016-09-20
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多