2013-10-21 52 views
21

目前我正在使用scanner/filereader並使用whilenextxtline。我認爲這種方法效率不高。有沒有其他方法可以用類似的功能來讀取文件?Java通過200萬行文本文件讀取最快速的方法

public void Read(String file) { 
     Scanner sc = null; 


     try { 
      sc = new Scanner(new FileReader(file)); 

      while (sc.hasNextLine()) { 
       String text = sc.nextLine(); 
       String[] file_Array = text.split(" ", 3); 

       if (file_Array[0].equalsIgnoreCase("case")) { 
        //do something 
       } else if (file_Array[0].equalsIgnoreCase("object")) { 
        //do something 
       } else if (file_Array[0].equalsIgnoreCase("classes")) { 
        //do something 
       } else if (file_Array[0].equalsIgnoreCase("function")) { 
        //do something 
       } 
       else if (file_Array[0].equalsIgnoreCase("ignore")) { 
        //do something 
       } 
       else if (file_Array[0].equalsIgnoreCase("display")) { 
        //do something 
       } 
      } 

     } catch (FileNotFoundException e) { 
      System.out.println("Input file " + file + " not found"); 
      System.exit(1); 
     } finally { 
      sc.close(); 
     } 
    } 
+0

此[鏈接](http://www.geeksforgeeks.org/fast-io-in-java-in-competitive-programming/)有一些很好的解決方案 – Joe

回答

23

你會發現,BufferedReader.readLine()是一樣快,你需要:你可以閱讀上百萬線的第二它。您的字符串拆分和處理更有可能導致您遇到的任何性能問題。

+0

我沒有做一次檢查但是當我使用緩衝讀取器時,我認爲讀取部分比掃描器快大約20% – BeyondProgrammer

+3

在我的情況下,分裂是文件讀取中最主要的因素。簡單使用indexOf/lastIndexOf和substring幫助將這些成本降至最低。 – lalitm

+0

對於我來說,一旦我用'substring()''''inputdex'()'對替換'split()',成本就降低了50%左右。 –

1

您可以使用JAVA NIO的FileChannelByteBuffer。 ByteBuffer的大小是我觀察數據的速度最快的部分。 下面的代碼將讀取文件的內容。

static public void main(String args[]) throws Exception 
    { 
     FileInputStream fileInputStream = new FileInputStream(
             new File("sample4.txt")); 
     FileChannel fileChannel = fileInputStream.getChannel(); 
     ByteBuffer byteBuffer = ByteBuffer.allocate(1024); 

     fileChannel.read(byteBuffer); 
     byteBuffer.flip(); 
     int limit = byteBuffer.limit(); 
     while(limit>0) 
     { 
      System.out.print((char)byteBuffer.get()); 
      limit--; 
     } 

     fileChannel.close(); 
    } 

你可以在這裏檢查'\ n'的新行。謝謝。


即使你可以散射和getter方法來讀取文件的速度即

fileChannel.get(buffers); 

其中

 ByteBuffer b1 = ByteBuffer.allocate(B1); 
     ByteBuffer b2 = ByteBuffer.allocate(B2); 
     ByteBuffer b3 = ByteBuffer.allocate(B3); 

     ByteBuffer[] buffers = {b1, b2, b3}; 

此作出幾個系統調用(可以是昂貴的節省了用戶進程),並且允許內核優化數據的處理,因爲它具有關於總傳輸的信息,如果有多個CPU可用,甚至可以同時填充和排出多個緩衝區狡猾。

this本書。

+1

如果正在將數據讀入JVM的Java端,則直接字節緩衝區沒有任何好處。如果您只是在兩個通道之間複製數據而不在Java代碼中查看它,則會帶來好處。 – EJP

+0

@EJP我知道。我在這裏刪除了該行,並發表了您的評論。 :-) – Trying

+0

@Trying,我想嘗試使用FileChannel你能提供我的任何例子從我的代碼上面? – BeyondProgrammer

0

您必須調查程序的哪個部分需要花費時間。

根據EJP的回答,您應該使用BufferedReader。

如果真的字符串處理需要時間,那麼你應該考慮使用線程,一個線程將從文件和隊列讀取線。其他字符串處理器線程將使隊列出隊並處理它們。您將需要調查使用多少個線程,您應該在應用程序中使用的線程數量必須與CPU中的內核數量相關,這樣才能使用完整的CPU。

+0

如何添加線程修復字符串處理問題? – EJP

+0

如果字符串處理花費時間,那麼多個花樣做同樣的事情會減少時間,就像並行處理一樣。 – UDPLover

+0

只有當一行的處理不依賴於其他行的處理時,這纔可用。 – UDPLover

-1

如果你想一起閱讀所有的行,那麼你應該看看java 7的API。它的使用非常簡單。

但是更好的方法是批量處理這個文件。有一個閱讀器從文件中讀取數據塊,還有一個寫入器負責執行所需的處理或保存數據。即使線路將來增加到十億條,也可以確保它能夠工作。你也可以有一個使用多線程來提高批處理性能的批處理。我會推薦你​​看看春季批次。

+0

「批次」在一次閱讀和處理一行文字時到底有多大幫助? – EJP

2

掃描儀不能像掃描儀使用正則表達式讀取文本文件一樣快,這使得它比緩衝讀取器更慢。通過使用bufferedReader(),你可以從文本文件中讀取一個塊。

BufferedReader bf = new BufferedReader(new FileReader("FileName")); 

您可以使用readLine()從bf中讀取數據。

希望它可以成爲你的目的

+1

我認爲你的意思是「掃描儀不能像BufferedReader一樣快」 – anon58192932

0

使用BufferedReader高性能文件訪問。但8192字節的默認緩衝區大小通常太小。對於大文件,您可以按大小順序increase the buffer size來提高您的文件讀取性能。例如:

BufferedReader br = new BufferedReader("file.dat", 1000 * 8192); 
while ((thisLine = br.readLine()) != null) { 
    System.out.println(thisLine); 
} 
+0

但它不會有太大的影響。 8192令人驚訝地足夠。 – EJP