2013-05-09 8 views
0

У меня есть текстовый файл с тысячами строк данных, таких как следующие:Чтение огромного текстового файла ascii быстро в Java. Нужна помощь по использованию MappedByteBuffer

38.48,88.25 
48.20,98.11 
100.24,181.39 
83.01,97.33 

... и этот список продолжает идти (тысячи строк просто так).

Я понял, как разделить эти данные в пригодных для использования маркеров с помощью FileReader и Сканер, но этот метод является слишком медленным.

Я создал следующий разделитель: src.useDelimiter (", | \ n");

, а затем использовать класс сканера nextDouble() для получения каждой части данных.

Я провел много исследований, и похоже, что решение должно использовать MappedByteBuffer, чтобы поместить данные в память и получить к нему доступ. Проблема в том, что я не знаю, как использовать MappedByteBuffer для разделения этих данных на используемые токены.

Я нашел этот сайт: http://javarevisited.blogspot.com/2012/01/memorymapped-file-and-io-in-java.html - который помогает мне отображать файл в память и объясняет, как читать файл, но похоже, что данные возвращаются в виде байта или, возможно, в двоичной форме? Файл, к которому я пытаюсь получить доступ, - ascii, и мне нужно также прочитать данные как ascii. Может ли кто-нибудь объяснить, как это сделать? Есть ли способ сканировать файл, отображаемый в память, таким же образом, как я сделал с помощью сканера с предыдущим методом FileReader? Или есть другой метод, который будет быстрее? Мой текущий метод занимает около 800 раз столько времени, сколько потребуется.

Я знаю, что некоторые могут сказать, что я пытаюсь изобретать колесо, но это для академических целей и, таким образом, мне не разрешено использовать внешние библиотеки.

Спасибо!

+0

вам нужно сохранить все данные в памяти или просто читать его строки в каждой строке делать. – Elmer

+0

Мне нужно прочитать строку в строке для запроса данных. В настоящее время этот процесс занимает около 40 секунд для обработки почти миллиона строк данных, но мне это нужно сделать быстрее. Если бы я мог сделать это менее чем за секунду, это было бы здорово. – etho201

+0

Я бы предложил сделать один проход по данным инициализации и сохранить его в соответствующей структуре в памяти. Тогда доступ к данным будет быстрым, и вам не нужно будет беспокоиться о скорости, с которой вы можете читать. – Elmer

ответ

0

Чтобы загрузить данные в память, вы можете использовать сканер так же, как и раньше, а затем хранить каждую строку в списке, как показано ниже.

List<Pair> data = new ArrayList<Pair>(); 

Где пара определяется как

class Pair { 

    private final double first; 
    private final double second; 

    public Pair(double first, double second) { 
    this.first = first; 
    this.second = second; 
    } 
    .... 
} 
+0

Я пытаюсь реализовать эту структуру, но я не могу понять, как назначить данные этой структуре. Я пробовал: data.add (double, double), но это не работает. Я попытался создать метод set в классе Pair, но он не позволит мне, так как «first» и «second» объявлены как «final». Я знаю, что могу изменить это, но я хочу, чтобы они были окончательными. Итак, как мне добавить элемент в этот список? – etho201

+0

Ответ можно найти здесь: http://stackoverflow.com/questions/16504569/adding-arraylist-items-to-a-user-defined-class-with-final-values-in-java – etho201

+0

Это все еще занимает 40 секунд, чтобы загрузить все это в память, но как только он там, я могу быстрее выполнять последующие поиски по этим данным. До этого потребуется 40 секунд для каждого поиска. Спасибо за это предложение! Есть ли способ загрузить это в память быстрее? – etho201

0

MappedByteBuffer является подклассом ByteBuffer, на котором вы можете позвонить asCharBuffer. Это возвращает CharBuffer, который реализует Readable, который затем может быть поставлен на Scanner.

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