簡體   English   中英

在java中以MB讀取大文件的最佳方法

[英]Best way to read huge file in MB in java

我正在閱讀帖子,它說使用BufferedReader或MappedByteBuffer。 我決定用291.0 MB文件自己測試,但仍然無法決定

    BufferedReader reader = new BufferedReader(new FileReader("/Users/rachana/part-00000"));
    String line = null;
    while((line = reader.readLine())!=null) {
        System.out.println(line);
    }


    ~~~~~~ Heap utilization in MB ~~~~~~
    Start Date  21:10:20
    End Date 21:17:48
    Time used 448 second
           7.50 min
    Used Memory In MB:28
    Free Memory:81
    Total Memory:109
    Max Memory:1820

使用MappedByteBuffer

RandomAccessFile aFile = new RandomAccessFile
                ("/Users/rachana/part-00000", "r");
        FileChannel inChannel = aFile.getChannel();
        MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
        buffer.load(); 
        for (int i = 0; i < buffer.limit(); i++)
        {
            System.out.print((char) buffer.get());
        }
        buffer.clear(); // do something with the data and clear/compact it.
        inChannel.close();
        aFile.close();



~~~~~~ Heap utilization in MB ~~~~~~
 Start Date  21:20:40
 End Date 21:33:52
 Time used 792 sec / 13.2 min
Used Memory In MB:4 
Free Memory:104
Total Memory:109
Max Memory:1820

它清楚地表明MappedByteBuffer使用更少的內存,但更多的時間,因為BufferedReader使用更多的內存但更少的時間。

我試圖找到平衡也使用MappedByteBuffer讀取行。

任何建議都會有所幫助

你正在做的最慢的部分是打印到屏幕上。 我建議你不要這樣做,你會很好的MemoryMapped文件更快(如果你不是一次打印一個字符到控制台)

注意:除非您使用的是IS-8859-1或US-ASCII編碼的文本文件,否則這兩個不可互換。 BufferedReader用於文本和內存映射文件用於二進制。

順便說一下如果忽略你執行的GC的數量,沒有必要查看使用的內存。 如果你只關心在開始和結束時使用的內存,你應該在測量之前用System.gc()做一個完整的GC,我希望在這兩種情況下你會看到一個小的,隨機的差異(可能是負面的)。

如果您關於分配的情況,您需要更大的伊甸園大小,例如2 GB,它開始為空(在完整GC之后),或者您可以使用分析器來測量分配。 在第一種情況下,字符串將分配最多的數據,在第二種情況下,寫入控制台將創建最多。

它清楚地表明MappedByteBuffer使用更少的內存,但更多的時間,因為BufferedReader使用更多的內存但更少的時間。

顯然,這不可能是真的,事實並非如此。 您使用MappedByteBuffer將整個300MB文件映射到內存中MappedByteBuffer,而不是使用BufferedReader 解釋是MappedByteBuffer內存不是來自堆。 它使用內存,與文件大小一樣多,這遠遠超過了你的BufferedReader代碼。 你不是在這里測量它。

類似地,您的時間測量也是無效的,因為它們由System.out.println()控制,它不是輸入,並且希望哪個也不是最終應用程序的一部分。

因此,您的基准測試在所有方面都完全無效。

使用BufferedReader 你可以每秒讀取數百萬行。 它足夠快。

我會選擇第一個,除非你真的試圖刮掉桶以進行內存優化。

原因:

  • 閱讀代碼更容易。
  • 用戶更有可能注意到比24 MB額外內存快100%的速度。

在進行文件I / O時,您應該記住,I / O操作可能比代碼中的CPU所做的任何工作都要慢得多。

但還有其他一些考慮因素。 優化往往會使代碼更復雜,更難理解。 要理解MappedByteBuffer代碼,讀者需要了解MappedByteBuffer如何工作以及他們需要理解文件輸入的所有內容。

文件閱讀通常是完成的。 因此,Java已經提供了幫助您的代碼,這一點不應該讓您感到驚訝。 該代碼將由專家編寫,經過測試和調試。 除非您有特殊要求,否則應始終使用此類代碼而不是自己編寫代碼。 也就是說,我建議使用BufferedReader (您的第一種方法)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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