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

plz*_*lme 2 java performance file-io memory-mapped-files

我正在阅读帖子,它说使用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
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

它清楚地表明MappedByteBuffer使用更少的内存,但更多的时间,因为BufferedReader使用更多的内存但更少的时间.

我试图找到平衡也使用MappedByteBuffer读取行.

任何建议都会有所帮助

Pet*_*rey 6

你正在做的最慢的部分是打印到屏幕上.我建议你不要这样做,你会很好的MemoryMapped文件更快(如果你不是一次打印一个字符到控制台)

注意:除非您使用的是IS-8859-1或US-ASCII编码的文本文件,否则这两个不可互换.BufferedReader用于文本和内存映射文件用于二进制.

顺便说一下如果忽略你执行的GC的数量,没有必要查看使用的内存.如果你只关心在开始和结束时使用的内存,你应该在测量之前用System.gc()做一个完整的GC,我希望在这两种情况下你会看到一个小的,随机的差异(可能是负面的).

如果您关于分配的情况,您需要更大的伊甸园大小,例如2 GB,它开始为空(在完整GC之后),或者您可以使用分析器来测量分配.在第一种情况下,字符串将分配最多的数据,在第二种情况下,写入控制台将创建最多.