深入理解javaIO原理

0 基础知识

在计算机体系结构中,计算机组成分为:运算器、控制器、存储器、输入设备、输出设备;操作系统会将所有的外设当做文件来处理,为了安全,操作系统内核并不会直接将外设暴露给应用程序,而是在内存中设置了缓冲区,当应用程序需要访问外设数据时,需要向操作系统申请,操作系统把数据放到内核缓冲区,然后将内核缓存区的数据复制到应用程序的内存中。

1 File类

File对象代表磁盘中实际存在的文件和目录。Java 把操作系统中的文件和目录都抽象成File,统一处理。

当new File(path)的时候生成的File对象,实际上是java内部对于文件的一个描述,当其调用一些获取长度等等,实际上是调用了对应native方法,即C++/C编写的代码;

2 InputStream

这是一个抽象类,定义了基础的读写的抽象方法。

3 FileInputStream

这是文件输入文件的实现类,继承了InputStream类,实现了其抽象方法。

3.1 创建

当new FileInputStream(file)的时候,实际上是在操作系统的文件系统中存在的一个文件file与java程序之间建立一个可以交互的连接,实际上就是一些约定标识符,底层调用了native open0方法,这也是C和C++写的。此时,文件的内容依然存放在外存,文件的描述被操作系统管理着,操作系统在文件描述和java程序之间建立可以交互的信任认可。

3.2 读

当调用read()方法的时候,层层调用告诉操作系统需要读这个文件了,由于操作系统管理文件是以页为单位的,一般是4kb,所以操作系统会执行一次系统调用,把一个页4kb的数据从外存复制到内存内核缓存区,接着根据java程序需要读的大小,把数据按照大小复制到变量(用户内存)的位置。当下一次读的时候操作系统首先判断内核缓冲区有没有,要是没有才从外存去读入;

4 BufferedInputStream

FileInputStream的问题在于每次读入的少,大量的开销花在从内核缓存区用户内存的变量
BufferedInputStream就是为了解决这个问题,这是一个装饰类,熟悉装饰者模式的朋友应该了解,就是在FileInputStream外面添加了一层,该装饰类最主要的是维护一个缓冲数组buf[],这个数组存在的意义在于,当read()的时候,操作系统复制4kb到内存内核缓存区,但是不是直接返回数据到变量,而是把内存内核缓存区的一页4kb内容复制到缓冲数组,当发现缓冲数组没有满的时候,继续从外存读入数据到内存内核缓存区,然后复制到缓冲数组,直到缓冲数组满。下一次读的时候,首先去缓冲数组找,要是没有就需要继续向操作系统申请数据。

5 最大文件打开数

程序能同时打开同一个文件个数,即文件和程序建立可信通道的个数是受限制的;
在Linux下面可以通过ulimit -n查看;默认是1024个文件;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值