Перебора 128-байтовых записей в файле


Я должна читать записи из текстового файла, где каждый 128 байт представляет собой логическую запись. Вызывающий модуль этого ниже читатель делает только следующее.

while(iterator.hasNext()){
    iterator.next();
    //do Something
 }

Значит, будет следующий() вызывать после каждого hasNext() вызова.

Сейчас здесь идет читатель.

public class FlatFileiteratorReader implements Iterable<String> {

    FileChannel fileChannel;

public FlatFileiteratorReader(FileInputStream fileInputStream) {
    fileChannel = fileInputStream.getChannel();
}

private class SampleFileIterator implements Iterator<String> {
    Charset charset = Charset.forName("ISO-8859-1");
    ByteBuffer byteBuffer = MappedByteBuffer.allocateDirect(128 * 100);
    LinkedList<String> recordCollection = new LinkedList<String>();
    String record = null;

    @Override
    public boolean hasNext() {
        if (!recordCollection.isEmpty()) {
            record = recordCollection.poll();
            return true;
        } else {
            try {
                int numberOfBytes = fileChannel.read(byteBuffer);
                if (numberOfBytes > 0) {
                    byteBuffer.rewind();
                    loadRecordsIntoCollection(charset.decode(byteBuffer)
                            .toString().substring(0, numberOfBytes),
                            numberOfBytes);
                    byteBuffer.flip();
                    record = recordCollection.poll();
                    return true;
                }
            } catch (IOException e) {
                // Report Exception. Real exception logging code in place
            }
        }
        try {
            fileChannel.close();
        } catch (IOException e) {
            // TODO Report Exception. Logging
        }
        return false;

    }

    @Override
    public String next() {
        return record;
    }

    @Override
    public void remove() {
        // NOT required

    }

    /**
     * 
     * @param records
     * @param length
     */
    private void loadRecordsIntoCollection(String records, int length) {
        int numberOfRecords = length / 128;
        for (int i = 0; i < numberOfRecords; i++) {
            recordCollection.add(records.substring(i * 128, (i + 1) * 128));
        }
    }

}

    @Override
    public Iterator<String> iterator() {
        return new SampleFileIterator();
    }
}

Код считывает 80 МБ данных в 1,2 секунды на машине с 7200 об / мин жесткий диск, с Sun JVM и под управлением операционной системы Windows ХР. Но я не доволен код, который я написал. Есть ли другой способ, чтобы написать это в лучшую сторону (особенно для декодирования набора символов и байтов, которые были считаны, я имею в виду кодировку.расшифруйте(byteBuffer) .метод toString().подстрока(0, numberOfBytes) части)?



236
1
задан 13 сентября 2011 в 09:09 Источник Поделиться
Комментарии
1 ответ


  1. Нет никакого преимущества в использовании прямой буфер. Вы должны получить данные через границу средой JNI в Java-земля, поэтому вы можете также использовать обычный ByteBuffer. Прямые буферы для копирования данных, если вы не хотите выглядеть действительно на него сами.

  2. Использовать ByteBuffer, кратный 512, например, 8192, так вы не едете на автомобиле системы ввода/вывода и контроллер диска с ума читает через границы сектора. В этом случае я бы подумал об использовании 128*512 согласиться с длиной записи.

  3. Интернет .подстрока(0, numberOfBytes) является ненужным. После чтения и назад, в ByteBuffer позиция равна нулю, а ее предел равен numberOfBytes, поэтому кодировку.декодировать() работа уже приносит правильное количество данных.

  4. Вы предполагаете, что вы не получите короткое чтение из FileChannel.читать(). Вы не можете предположить, что нет ничего в документации, чтобы поддержать это предположение. Читать нужно до тех пор, пока буфер не будет заполнен или вы получите ВФ.

Сказав Все это, я также хотел экспериментировать с bufferedreader вокруг себя InputStreamReader вокруг FileInputStream, а просто читать 128 символов одновременно. Вы можете сделать сюрприз, какой быстрее.

2
ответ дан 14 сентября 2011 в 12:09 Источник Поделиться