java文件读写(磁盘IO机制详解)

当我参加第四届中间件比赛的时候,我就对这文件读写很懵逼,好多种读写方式,啥区别,效率都啥样,于是翻看了好多的资料,真的不全啊,有的单独说系统,有的单独说java,也不知道谁真谁假。于是根据我查找的资料和实际的源码阅读,我总结这篇文章,希望各位像我一样懵逼过得同学能不太懵逼,希望有理解不到位的地方各位大佬能指点一二。

即将毕业,会陆续开始写一些java方面的文章,希望能为找工作带来些帮助,各位大佬关注一下!

JAVA磁盘IO的前世今生:

很早的时候,各种InputStream OutputStream等等,这些都是基于流的IO,这种IO过时了,流还要分为输入流和输出流

现在广泛用NIO了,NIO是基于通道Channel的,通道当然就是双向的,一个通道既可以输入又可以输出。而且上面的载体是Buffer,也就是‘块’,而非之前的‘流’。

后面我只说NIO,我个人认为NIO可以代替传统的流了吧

JAVA NIO中的‘载体’——Buffer:

首先载体是块,常用ByteBuffer。也就是与磁盘之间的传输的内容都在这个里面。

看图可知道,这个载体有三类:HeapByteBuffer、DirectByteBuffer、MappedByteBuffer。其中前一个是堆内的byte数组,后两个是堆外的,堆外的意思就是是用jni调用C来malloc的内存,这个内存不在堆内无法gc。

关于Buffer的细节我以后的博文会写一些。

linux文件IO机制:

首先补充一下系统的知识,用户态对应内存的用户空间,也就是我们程序所申请的空间。内核态对应内存的内核空间。系统调用就是从用户态到内核态的一个接口。

听起来感觉没用是吧,以普通方式文件读为例:程序一开始工作在用户空间,然后要读文件,调用read系统调用,转到内核态,DMA进行磁盘io,将数据读到内核空间的缓存(pagecache)中,然后cpu再从pagecache copy到用户空间来,切换为用户态。

上面基础知识了解之后,看一下Linux下的几种不同的磁盘IO:

1.最常见的机制(缓存IO):用户空间<——>内核空间(pagecache)<——>磁盘

2.内存映射机制(mmap):还是有内核区的pagecache,只不过用户空间和内核空间的pagecache有内存映射,减少一次copy

3.直接IO(DIO):不经过内核缓冲区,直接用户空间<——>磁盘

4.异步IO

磁盘IO的零拷贝指的就是2和3

 

JAVA中磁盘NIO呢?

java不像C++可以那么底层的操作,所以有一定的限制。看一下我总结出来JAVA磁盘NIO的四种方法以及是数据走向

1.filechannel+HeapByteBuffer:堆内<->堆外<->pagecache<->磁盘

2.filechannel+DirectByteBuffer:堆外<->pagecache<->磁盘

3.MappedByteBuffer:堆外<->pagecache<->磁盘 (其中堆外与pagecache有内存映射不需要copy)

4.异步channel

可以看出java没办法直接IO,当然了可以通过jni调用C来实现,这是一种骚操作了。

效率上的差距和注意点呢?

经过首届POLARDB数据库性能大赛的磨练,当然是2、3要好一些了,但是还有些细节要注意,以后说吧。后面我会写一下我们比赛的攻略(第七名),和Buffer使用以及网络NIO等等

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值