JAVA NIO(六):读取10G的文件其实很容易

读取10G的文本文件,我们可能会直接认为,这太难了,这涉及到内存的容量,硬盘的读取速度以及虚拟内存、页失败载入等概念,其实对JAVA,读取10G的文件轻而易举,无论bio(java.io)还是nio,都能轻松完成任务。本次测试的10G文件,来源于上篇文章《JAVA NIO(五):如何在5秒内写入10G的文本数据》的实验结果。

1. FileInputStream VS BufferedInputStream

不用做任何优化,也不用调用任何第三方库,FileInputStream即可独立完成工作,并且仅仅消耗内存20M。

跟FileInputStream相比,BufferedInputStream并没有体现出任何性能优势,以下是它们的成绩对比:

实现方式文件大小执行时间消耗内存
FileInputStream9.5G22.82641180920M
BufferedInputStream9.5G22.6041550820M

FileInputStream的实现代码如下:

private static long readByFis(File file) throws FileNotFoundException, IOException {
    InputStream is = new FileInputStream(file);
    byte[] buff = new byte[4096];
    long counts = 0;
    int offset = 0;
    while((offset = is.read(buff)) != -1) {
        counts = counts + offset;
    }
    is.close();
    return counts;
}

2. BufferedReader

对于字符处理,BufferedReader通常是我的第一选择,但从我多次测试的结果来看,字符的处理效率远远低于二进制的处理效率(内存消耗与处理时间都有较大幅度的增长),以下是成绩对比及代码实现:

实现方式文件大小执行时间消耗内存
BufferedReader9.5G28.607785218S40M
BufferedInputStream9.5G22.6041550820M
private static long readByBos(File file) throws FileNotFoundException, IOException {
    long counts = 0;
    int offset = 0;
    BufferedInputStream bos = new BufferedInputStream(new FileInputStream(file));
    byte[] buff = new byte[4096];
    while((offset= bos.read(buff)) != -1) {
        counts = counts + offset;
    }
    bos.close();
    return counts;
}

说一句体外话,对于文件编辑器,经常出现卡顿、卡死打不开文件的原因,大部分的原因都不在于磁盘IO与内存,而在于文本处理与排版。

3. 文件通道与直接内存

在文件读取操作中,直接内存依旧没有显示出性能优势,以下是他们的成绩对比:

实现方式文件大小执行时间缓冲区大小
非直接内存9.5G27.8521949032M
非直接内存9.5G27.0831225254M
直接内存9.5G27.3746426412M
直接内存9.5G27.3323832894M

现在我很怀疑,到底是JAVA对传统的IO进行了较大幅度的优化,还是nio的优势根本就不在于性能,因为读取速度上,nio表现依旧很平凡,以下是实现代码:

private static long readByChannel() throws FileNotFoundException, IOException {
    long counts = 0;
    File file = new File("bigFile.txt");
    FileInputStream fis = new FileInputStream(file);
    FileChannel fc = fis.getChannel();
    ByteBuffer bbuf = ByteBuffer.allocate(2048);
    int offset = 0;
    while((offset = fc.read(bbuf)) != -1) {
        counts = counts + offset;
        bbuf.clear();
    }
    fc.close();
    fis.close();
    return counts;
}

4. 内存映射

这里的操作技巧最强,但总体来说,映射的内容越大越好,对于反复处理的内容,性能优势较为明显,这里打算单独来进行评测。

结论

读取10G的文件,JAVA的传统API即可轻松完成,并且性能卓越,至于NIO,强化的可能不仅仅是性能,而是新的编程方式与阻塞处理机制。

  • 4
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值