2016-06-10 2 views
0

Я использую ниже код для чтения большого файла XML (в ГЗ) в Hadoop RecordReader с использованием XMLStreamReaderКак getProgress больших файлов с помощью XMLStreamReader

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?, но не могу использовать userReader. Пожалуйста, помогите мне здесь.

+0

Вы знаете полную длину потока? – biziclop

+0

нет, с stax это невозможно, так как он использует потоковое воспроизведение, поэтому не может получить весь размер файла. –

+0

Я имею в виду, откуда-то еще. Потому что, если вам не удастся определить общую длину ваших данных ** до того, как вы начнете ее передавать, вам не удастся отслеживать прогресс. – biziclop

ответ

2

Вы можете обернуть InputStream, расширив FilterInputStream.

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 
+0

Фактически я использую org.apache.hadoop.mapreduce.RecordReader и должен прочитать прогресс внутри него. Не могли бы вы помочь мне здесь. –

+0

Итак, обновите ход пользовательского 'InputStreamListener'. Чтобы получить предварительный уровень, вам понадобятся общие байты. 'InputStream.available()' НЕ гарантирует возврат всех байтов (он возвращает общее число, которое можно прочитать без блокировки). Но вы можете обнаружить, что этот метод работает (в зависимости от реализации InputStream) –

+0

Я попытался использовать метод '.available()', но здесь общее количество байтов чтения и доступных байтов всегда одинаково. –

Смежные вопросы