2011-12-14 42 views
3

我有wiki.txt文件,其大小爲50 MB。將文本文件加載到Java中的內存

  1. 我需要在文件上做幾件事情,所以我認爲性能方面的最佳方式是將文件加載到內存中,是否正確?

  2. 這是我寫的代碼:

    File file = new File("wiki.txt"); 
    FileInputStream fileInputStream = new FileInputStream(file); 
    FileChannel fileChannel = fileInputStream.getChannel(); 
    MappedByteBuffer mapByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); 
    System.out.println((char)mapByteBuffer.get()); 
    

我對這個代碼得到錯誤:mapByteBuffer.get()。 我嘗試了get()函數幾個選項,但所有他們我得到的錯誤,甚至沒有在e.getMessage()我得到了一個錯誤。

另一個重要的事情要注意,我的文本文件包含英語單詞和我需要做的動作是搜索,如果表達存在這個文本文件。

謝謝。

+2

你會得到哪個錯誤? – bvd 2011-12-14 07:45:52

+0

請發佈您收到的錯誤消息。此外,從文本文件中查看一些樣本行會有所幫助 - 然後我們可以提出一種有效的方式來閱讀和存儲它(您顯示的代碼背後嚴重缺乏理解)。 – 2011-12-14 07:59:10

回答

3

我會建議使用MemoryMappedFile,直接從磁盤讀取文件,而不是將其加載到內存中。

RandomAccessFile file = new RandomAccessFile("wiki.txt", "r"); 
FileChannel channel = file.getChannel(); 
MappedByteBuffer buf = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024*50); 

然後你就可以讀取緩衝區如常。

1

我會建議使用BufferedReader。它速度更快,所需資源相對較少。線 首先閱讀數:

InputStream is = new BufferedInputStream(new FileInputStream(filename)); 
byte[] chars = new byte[1024]; 
int numberOfChars = 0; 
while ((numberOfChars = is.read(chars)) != -1) 
{ 
    for (int i = 0; i < numberOfChars; ++i) 
    { 
     if (chars[i] == '\n' && numberOfChars - i != 1) 
     { 
      ++count; 
     }   
    } 
} 
count++ 
return count; // number of lines 

然後讀線:

BufferedReader in = new BufferedReader(new FileReader(fileName)); 
for (int i = 0; i < endLine; i++) 
{ 
    String oneLine = in.readLine(); 
} 

在這個字符串,你甚至可以搜索您所需要的。

+0

但是我需要回顧一下幾種不同的表達方式,當我再次瀏覽整個文件時,真的會更好嗎? – 2011-12-14 16:31:36

+0

不是一個好主意。 如果我的字符串在50MB文件的末尾,所以這需要很長時間。 – 2011-12-15 07:47:59

2

我的回答對點(1):

這取決於你想用文件做什麼。如果您的處理不涉及倒帶操作(查看後面/之前讀取的內容),最好只讀取流並一次處理它(而不是全部加載到內存中)。

即使您需要跨文件進行隨機訪問,也可能對塊文件操作感興趣,因爲當文件大小變爲較大時,解決方案可能無法很好地擴展。 RandomAccessFile如果您使用Java 1.4或更高版本。 對於隨機訪問,操作系統通常會很好地處理文件緩衝區緩存,您不必自己處理。

2

重要的是要讀取整個錯誤,而不僅僅是消息。通常情況下,真實的信息是以例外的名稱而不是與其相關的文本。

如果由於沒有第一個字節而導致文件爲空,您將會收到錯誤。

注意:您使用的方法採用ASCII 7位字符。如果你想假設ISO-8859-1字符,你可以使用(char) (byteBuffer.get() & 0xFF)

但是,如果你有計劃文本,你可能會發現使用字符串更簡單,使用起來並不慢。例如您可以在不到一秒的時間內以文本形式讀取50 MB文件。如果這太長,我只會使用內存映射文件。

相關問題