2011-04-27 3 views
7

Для обработки журнала мое приложение должно читать текстовые файлы по строкам. Сначала я использовал функцию readLine() BufferedReader, но я читал в Интернете, что BufferedReader работает медленно при чтении файлов.
Затем я попытался использовать FileInputStream вместе с FileChannel и MappedByteBuffer, но в этом случае нет никакой функции, аналогичной ReadLine(), поэтому я искать свой текст для разрыва строки и обрабатывать его:Самый быстрый способ чтения текстового файла по строкам в Java

try { 
     FileInputStream f = new FileInputStream(file); 
     FileChannel ch = f.getChannel(); 
     MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, 0L, ch.size()); 
     byte[] bytes = new byte[1024]; 
     int i = 0; 
     while (mb.hasRemaining()) { 
      byte get = mb.get(); 
      if(get == '\n') { 
       if(ra.run(new String(bytes))) 
        cnt++; 
       for(int j = 0; j<=i; j++) 
        bytes[j] = 0; 
       i = 0; 
      } 
      else 
       bytes[i++] = get; 
     } 
    } catch(Exception ex) { 
     ex.printStackTrace(); 
    } 

Я знаю, что это вероятно, не является хорошим способом его реализации, но когда я просто читаю текстовый файл в байтах, он в 3 раза быстрее, чем при использовании BufferedReader, но вызов new String(bytes) создает новую строку и делает программу еще медленнее, чем при использовании BufferedReader.
Итак, я хотел спросить, что является самым быстрым способом чтения текстового файла по строкам? Некоторые говорят, что BufferedReader - единственное решение этой проблемы.

P.S .: ra является экземпляром RunAutomaton из библиотеки dk.brics.Automaton.

+1

BufferedReader действительно слишком медленный для ваших нужд? Это, вероятно, один из самых чистых, наиболее удобных в использовании решений, если вы должны закодировать на Java. –

+0

Если 'BufferedReader' действительно слишком медленный для вашего приложения, вы должны подумать о том, что не используете java или другие управляемые языки ... _ (Но я сомневаюсь, что это так) _ – ordag

+1

[Aaron] (http: // stackoverflow. com/users/460201/aaron) ответ будет удален как ответ только для ссылки, поэтому я поставлю его здесь как комментарий: «Проверьте [эту ссылку] (http://nadeausoftware.com/articles/ 2008/02/java_tip_how_read_files_quickly). Он содержит сравнение скорости различных методов ». –

ответ

19

Я очень сомневаюсь, что BufferedReader вызовет значительные накладные расходы. Добавление собственного кода скорее всего будет неэффективным и, возможно, неправильным.

Например, в коде, который вы указали, вы вызываете new String(bytes), который всегда будет создавать строку из 1024 байтов, используя стандартную кодировку платформы ... не очень хорошая идея. Конечно, после этого вы очищаете массив, но ваши строки по-прежнему будут содержать кучу символов «\ 0», что означает много потерянного пространства, кроме всего прочего. Вы должны не менее ограничить часть массива байтов, из которой создается строка (что также означает, что вам не нужно очищать массив после этого).

Вы на самом деле попробовали используя BufferedReader и обнаружили, что это слишком медленно? Обычно вы должны написать простейший код, который сначала будет соответствовать вашим целям, а затем проверить, достаточно ли он ... особенно, если ваша единственная причина не делать этого - это неопределенный ресурс, который вы «читаете в Интернете». Вы хотите, чтобы я нашел сотни примеров того, как люди неверно отзывались о предложениях? :)

В качестве альтернативы вам может потребоваться перегрузка GuavaFiles.readLines(), которая принимает LineProcessor.

+1

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

+2

@Yoni: «очень быстро» - довольно расплывчатое требование. У вас даже есть доказательства того, что «BufferedReader» является узким местом, а не (что гораздо более вероятно) скоростью физического диска? –

+0

Если я читаю одни и те же файлы в байтах, это в 3 раза быстрее, чем при использовании 'BufferedReader'. Скорость моего жесткого диска составляет около 150 Мб/с, а моя программа читается со скоростью 30 Мб/с. – Yoni

2

Using plain BufferedReader I got 100+ MB/s. Очень вероятно, что скорость, с которой вы можете прочитать данные с диска, - это ваша шея бутылки, поэтому, как вы делаете чтение, не будет иметь большого значения.

BufferedReader - это не единственное решение, но оно достаточно быстро для 99% случаев использования, поэтому зачем делать вещи более сложными, чем они должны быть?

0

У меня очень простой цикл, который считывает около 2000 строк (50 тыс. Байт) из файла на SD-карте с использованием BufferedReader, и он читает их все примерно в 100 мс в режиме отладки на вкладке галактики 2. Не так уж плохо. Затем я поставил сканер в петле и время прошло через крышу (десятки секунд), а также множество GC_CONCURANT сообщений

Scanner scanner = new Scanner(line); 
int eventType = scanner.nextInt(16); 

так, по крайней мере в моем случае его сканер, что это проблема, я думаю, что мне нужно сканировать ints по-другому, но я понятия не имею, почему это может быть так медленно

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