2012-10-27 51 views
4

如何將文件加載到主內存中?讀取文件vs從磁盤加載文件到主內存以進行處理

我使用, 讀取文件我用

BufferReader buf = new BufferedReader(FileReader()); 

我相信,這是通過從磁盤讀取行的文件行。這有什麼好處?

將文件直接加載到內存中的優點是什麼? 我們如何在Java中做到這一點?

我在ScannerRandomAccessFile方法中找到了一些例子。他們是否將文件加載到內存中?我應該使用它們嗎?我應該使用哪兩個?

在此先感謝!

+2

你的[profiler](http://stackoverflow.com/q/2064427/230513)是什麼意思? – trashgod

+0

你認爲你的堆在哪裏? (「將文件加載到內存中」是一個毫無意義的表達式。) –

+0

我沒有分析器。我在hadoop集羣上運行程序,並使用cygwin監視。我想要一種方式直接將文件加載到內存中,而不是從磁盤逐行讀取。我認爲堆是動態的memeory分配。除此之外,我對此沒有想法。請幫忙! –

回答

7
BufferReader buf = new BufferedReader(FileReader()); 

我相信,這是通過從磁盤讀取行的文件行。這有什麼好處?

不完全是。它正在讀取大小爲默認緩衝區大小的塊(我認爲是8k字節)。

好處是你不需要巨大的堆來讀取一個巨大的文件。這是一個重要的問題,因爲最大堆大小隻能在JVM啓動時指定(使用Hotspot Java)。

您也不會消耗系統的物理/虛擬內存資源來表示巨大的堆。

將文件直接加載到內存中的優點是什麼?

它減少了系統調用的次數,並且可能更快地讀取文件。快多少取決於許多因素。而且你有處理真正大文件的問題。

我們如何在Java中做到這一點?

  1. 找出文件有多大。
  2. 分配一個足夠大的字節(或字符)數組。
  3. 使用相關的read(byte[], int, int)read(char[], int, int)方法來讀取整個文件。

您也可以使用內存映射文件...但這需要使用Buffer API,這可能有點棘手。

我發現了一些關於Scanner或RandomAccessFile方法的例子。他們是否將文件加載到內存中?

不,沒有。

我應該使用它們嗎?我應該使用哪兩個?

它們是否提供了您需要的功能?你需要讀取/解析基於文本的數據嗎?你需要對二進制數據進行隨機訪問嗎?

在正常情況下,您應該主要根據您需要的功能選擇您的I/O API,其次考慮性能因素。如果您打算在閱讀時解析它,則使用BufferedInputStreamBufferedReader通常就足以獲得可接受的性能。 (但是,如果你真的需要保留在內存中的整個文件在其原來的形式,那麼BufferedXxx包裝類實際上使讀慢一點。)


* - 請注意,接受表現不與最佳性能相同,但您的客戶/項目經理可能不希望您浪費時間編寫代碼以實現最佳性能......如果這不是明確的要求。

+0

我需要讀取和解析文件。我很喜歡這個hadoop map reduce程序。我正嘗試使用緩衝讀取器從磁盤讀取文件。但這似乎需要很長時間。所以,我想知道可能是我應該將整個文件加載到內存中,這可能會提高性能。 –

+0

您需要對您的應用程序進行配置,以確定它在閱讀/解析中花費的時間。 –

+1

請注意,如果您的意圖是在不解析的情況下讀取整個文件,則Buffered包裝器將僅向操作添加額外的副本。但是,如果您正在閱讀文件,解析文件,然後再不參考文件,您需要一個緩衝讀取器,並且一次讀取整個文件可能是一個壞主意。 –

3

如果您正在閱讀文件然後解析它,從頭到尾行走一次以提取數據,然後不再引用該文件,緩衝讀取器就像您將獲得的「最佳」一樣。您可以通過調整緩衝區大小來「調整」性能 - 較大的緩衝區將從文件中讀取較大的塊。 (使緩衝區爲2的冪 - 例如262144.)讀取整個大文件(大於1mb)通常會導致您在分頁和堆管理中的性能。

+0

謝謝,會試試! –

相關問題