2011-04-27 120 views
7

對於日誌處理,我的應用程序需要逐行讀取文本文件。 首先,我使用了BufferedReader函數readLine(),但是我在網上讀到BufferedReader在讀取文件時速度很慢。
後來我嘗試了與FileChannel和MappedByteBuffer一起使用的FileInputStream但在這種情況下,有沒有類似的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(); 
    } 

我知道這可能不是實現它的好方法,但是當我以字節讀取文本文件時,使用BufferedReader的速度比使用BufferedReader快3倍,但調用new String(bytes)會創建一個新的String,並且在使用BufferedReader時使程序更慢。
所以我想問一下按行讀取文本文件的最快方法是什麼?有人說BufferedReader是解決這個問題的唯一方法。

P.S .: ra是來自dk.brics.Automaton庫的RunAutomaton的一個實例。

+1

是BufferedReader真的太慢了​​嗎?如果您必須使用Java編碼,那麼它可能是最乾淨,最易維護的解決方案之一。 – 2011-04-27 06:45:17

+0

如果'BufferedReader'對於您的應用程序來說真的太慢了​​,您應該考慮不要使用java或其他託管語言...... _(但我懷疑是這種情況)_ – ordag 2011-04-27 12:28:13

+1

[亞倫](http:// stackoverflow。 com/users/460201/aaron)的答案即將被刪除,因此我將其作爲評論放在這裏:「檢查[此鏈接](http://nadeausoftware.com/articles/) 2008/02/java_tip_how_read_files_quickly)out。它包含了各種方法的速度比較。「 – 2014-07-14 09:29:44

回答

19

我非常懷疑BufferedReader會造成重大的開銷。添加你自己的代碼可能至少是效率低下的,很可能也是錯誤的。

例如,在您給出的代碼中,您打電話給new String(bytes),它總是要從1024字節創建一個字符串,使用平臺默認編碼...不是一個好主意。當然,之後你會清除數組,但是你的字符串仍然會包含一串'\ 0'字符 - 這意味着除了其他任何東西之外,還有很多浪費的空間。你應該至少限制正在創建字符串的字節數組部分(這也意味着你不需要清除數組)。

你實際上試過使用BufferedReader,發現它太慢?你通常應該編寫最簡單的代碼,它將首先滿足你的目標,然後檢查它是否足夠快,特別是如果你不這樣做的唯一原因是你「在互聯網上閱讀」的未指定資源。你想讓我找到數以百計的人發表不正確的表演建議的例子嗎? :)

作爲一種替代方案,您可能需要查看GuavaFiles.readLines()的超載,它需要LineProcessor

+1

我已經嘗試過BufferedReader,它表現良好,但程序的要求是非常快,所以我只是試圖找出哪個解決方案是我的最佳實施方案。 – Yoni 2011-04-27 06:57:49

+2

@Yoni:「非常快」是一個相當模糊的要求。你甚至有任何證據證明它是'BufferedReader',它是物理磁盤速度的瓶頸,而不是(很有可能)? – 2011-04-27 06:59:14

+0

如果我以字節讀取相同的文件,那麼使用'BufferedReader'時會快3倍。我的硬盤速度約爲150mb/s,而我的程序讀數爲30mb/s。 – Yoni 2011-04-27 07:07:38

2

Using plain BufferedReader I got 100+ MB/s。從磁盤讀取數據的速度很可能是你的瓶頸,所以你如何做閱讀不會有太大的區別。

BufferedReader不是唯一的解決方案,但它對於99%的用例足夠快,那麼爲什麼要使事情比他們需要的更復雜呢?

0

我有一個非常簡單的循環,它使用BufferedReader從sdcard上的一個文件讀取大約2000行(50k字節),它在galaxy選項卡2上以調試模式在100mS左右讀取它們。不是太糟糕。然後我把掃描儀的循環和時間通過屋頂(幾十秒)去了,再加上很多GC_CONCURANT消息

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

因此至少在我的情況下,它是那樣的問題,掃描儀,我想我需要以另一種方式掃描整數,但我不知道爲什麼它可能會如此緩慢

相關問題