[英]Reading text file to string without huge memory consumption
我嘗試測量幾種方法的性能,這些方法使用NIO(讀取單個文件最慢),BufferedInputStream並逐行讀取文件(每遍平均600毫秒),然后使用Filereader和數組讀取此流,將文件讀取為字符串具有固定大小的緩沖區(最快)
文件是Windows .txt文件格式的95 MB純文本。 將chars轉換為字符串確實是瓶頸,但是我注意到的是此方法的巨大內存消耗。 對於95 MB的lorem ipsum,這將消耗多達1 GB的RAM。 我還沒找到原因。
我嘗試過的沒有效果:
通過調用System.gc()發出垃圾回收器,以在方法結束之前將所有指針變量設置為null(但是無論如何它們都應該在方法內部定義)。
private void testCharStream() {
File f = f = new File("c:/Downloads/test.txt");
long oldTime = System.currentTimeMillis();
char[] cbuf = new char[8192];
StringBuilder builder = new StringBuilder();
try {
FileReader reader = new FileReader(f);
while (reader.read(cbuf) != -1) {
builder.append(cbuf);
}
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long currentTime = System.currentTimeMillis();
System.out.println(currentTime - oldTime);
}
嘗試Apache Commons IO: http : //commons.apache.org/proper/commons-io/我沒有對其進行基准測試,但是我認為代碼已經過優化。
我想出了一個不錯的解決方案。 使用Apache Commons IO軟件包,內存峰值為777,1 MB ,最低的220 MB和710 ms的平均內存需要使95 MB的文本文件變為紅色。
我所做的是在方法末尾將指向StringBuilder對象的指針的變量設置為null,並建議垃圾回收器實際完成此工作(System.gc())。 內存峰值為540 MB ,是之前達到的值的1/2以上! 同樣,通過將緩沖區大小更改為1024,意味着每遍可從490改善到450,甚至更少,可改善40 ms。 因此,我的函數僅需要Apache的63.4%的時間即可讀取文件。 幾乎減少了40% 。 有什么想法可以使性能進一步提高嗎?
這是功能。
private void testCharStream() {
long oldTime = System.currentTimeMillis();
char[] cbuf = new char[1024];
StringBuilder builder = new StringBuilder();
try {
FileReader reader = new FileReader(f);
while (reader.read(cbuf) != -1) {
builder.append(cbuf);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
long currentTime = System.currentTimeMillis();
builder = null;
System.gc();
System.out.println(currentTime - oldTime);
}
為了獲得更好的性能,您可以使用BufferedReader 。 此類允許您逐行讀取文件。 與通過逐字讀取文件來浪費時間相比,此方法將更快地執行任務。 您可以在半秒內讀取純文本文件(大小:1 MB)。 只需使用以下代碼。
File f = new File(“ File path”);
FileReader fr = new FileReader(f)
BufferedReader br = new BufferedReader(fr);
字符串line =“”;
StringBuilder builder = new StringBuilder();
嘗試{
而((行= br.readLine())!= NULL)
builder.append(線+ “\\ n”);
}
catch(異常e)
{
e.printStackTrace();
}
使用System.currentTimeMillis()
時,您可以檢查讀取文件所需的時間。
請看下面的鏈接,閱讀《使用Java的真正大文件》(150GB)。
[ http://www.answerques.com/s1imeegPeQqU/reading-really-big-files-with-java][1]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.