2017-10-13 36 views
1

所以基本上,對於我正在處理的這個任務,我們必須從一個大約一百萬行的大文件讀入,將關鍵字和值存儲在我們選擇的數據結構(我使用散列表)提供了更改鍵值的功能,然後將鍵值存儲保存迴文件中。我正在使用杜鵑哈希方法以及我從哈佛大學一篇名爲「存儲」的文章中找到的方法來完成這一任務,我對它的所有方面都很滿意。我唯一擔心的是隻用程序讀取文件中的數據的時間。如何加速從一個大文件讀取(Java)

文件格式,因此每行有這樣寫的一個鍵(整數)和值(字符串):

12345 'ABCDEF'

23456 'bcdefg'

等上。我已經拿出來閱讀的方法是這樣的:

private static void readData() throws IOException { 
    try { 
     BufferedReader inStream = new BufferedReader(new FileReader("input/data.db")); 
     StreamTokenizer st = new StreamTokenizer(inStream); 
     String line = inStream.readLine(); 
     do{ 
      String[] arr = line.split(" "); 
      line = inStream.readLine(); 
      Long n = Long.parseLong(arr[0]); 
      String s = arr[1]; 
      //HashNode<Long, String> node = HashNode.create(n, s); 
      //table = HashTable.empty(); 
      //table.add(n, s); 

     }while(line != null); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 

的方法工作正常,實際上得到的數據,但是我有一百萬行我們的測試文件測試,它花了大約20分鐘,它通過閱讀所有內容來獲取所有內容。當然,這不是從文件中讀取數據的快速時間,我認爲必須有更好的方式來完成這項工作。

我已經嘗試了幾種不同的輸入方法(使用FileInputStream的BufferedInputStream,使用掃描程序,但是文件擴展名是.db所以Scanner沒有工作,我最初沒有tokenizer,但添加它希望它會有所幫助) 。我不知道我運行它的計算機是否有很大的不同。我有一臺MacBook Air,目前我正在運行;然而,我有一個伴侶在他的筆記本電腦上運行它,看看它是否可以幫助它。任何關於如何幫助這個事情的投入,或者我可能會做什麼來減慢事情都會非常誠懇和非常感激。

P.S.請不要恨我在Mac上編程:-)

回答

1

可以使用,下面的代碼是用Java編寫8風格,但如果需要,可以很容易地修改Java的早期版本:

 Map<Long, String> map = new HashMap<>(); 
     Files.lines(Paths.get("full-path-to-your-file")).forEach(line -> { 
      String[] arr = line.split(" "); 
      Long number = Long.parseLong(arr[0]); 
      String string = arr[1]; 
      map.put(number, string); 
     }); 

有一個額外的自Files.lines(..).forEach(...)以來並行執行的性能增益。這意味着線路不會按順序排列(在我們的情況下 - 您不需要它),以防您需要它以便您可以撥打:forEachOrdered()

在我的MacBook上,花費不到5秒的時間將200萬條這樣的記錄寫入文件,然後讀取並填充地圖。

+1

這對我來說真棒。我調整了程序的其餘部分,完成了散列函數,現在需要大約2秒鐘才能讀取和存儲100萬行。謝謝! – koko985

1

擺脫StreamTokenizer。您可以使用BufferedReader.readLine()讀取每秒數百萬行,這就是您真正在做的事情:無需標記。

但我強烈懷疑這段時間沒有花在I/O上,而是在處理每一行。

NB你do/while循環通常寫成while循環:

while ((line = in.readLine()) != null) 

更清晰的那樣,並沒有NPE的風險。 「java.nio.file *」

+0

我已經等待代碼完全計算,最後沒有錯誤。另外,我有意忽略第一行,第一行是一個包含文件名稱的頭文件,我不想讓它讀入。不幸的是,這是整個Main類,而不是簡單地調用此方法的main方法,那到目前爲止。我將移除標記器以查看是否可以以任何方式提供幫助。 – koko985