簡體   English   中英

將文本文件讀取為字符串,而不會占用大量內存

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM