前言
I/O问题从你开始使用电脑时就要接触,例如你打开电脑,还未进入操作系统时,最先进入的是BIOS(Basic Input/Output System),也是就是主板的系统,作为使用电脑的一步就已经开始涉及IO了,作为人机交互的第一步,I/O是机器获取和交换信息的主要渠道。
1.I/O分类
在Java中java.io下大概有接近80个类,进行以下分组:
- 基于字节操作的I/O接口:InputStream和OutputStream。
- 基于字符操作的I/O接口:Writer和Reader。
- 基于磁盘操作的I/O接口:File。
- 基于网络操作的I/O接口:Socket。
注意:Socket类并不在java.io下
核心问题
- 数据格式
2.传输方式
1.1 基于字节的I/O操作接口
基于字节的I/O操作接口输入和输出分别是InputSream和OutputStream,层次结构如下:
1.2磁盘I/O工作机制
(1)标准访问文件的方式
当应用程序调用read()接口时,操作系统检查在内核的高速缓存中没有需要的数据,如果已经缓存了,那么就直接从缓存中返回,如果没有,则从磁盘中读取,然后缓存在操作系统的缓存中。
写入的方式是,调用write()接口,将数据从用户地址空间复制到内核地址空间的缓存中。这时对用户程序来说写操作就已经完成,至于什么时候再写到磁盘中,由操作系统决定,除非显式调用了sync同步命令。
(2)直接I/O方式
所谓的直接I/O的方式就是应用程序直接访问磁盘数据,而不是经过操作系统内核数据缓冲区,这样做的目的就是减少一次从内核缓冲区到用户程序缓存的数据复制。
(3)同步访问文件的方式
(4)异步访问文件的方式
(5)内存映射的方式
1.3 解释
以上磁盘的工作机制基本都是抄书的,如果只是抄书,我觉得毫无意义,还不如直接去看书呢。
我在这里想解释一下,很多人都把内存和磁盘混为一谈,比如你这手机内存多大的呀?128G。每当听到这样的对话,我都会默许他说的其实是磁盘存储空间,而不是真的内存大小。当我们运行或者打开这个文件时,我们会将这个程序读到内存里去,这就是为什么内存越大,可同时运行的程序越多。
一个可以明显感知到磁盘和内存区别,就是我们在装系统的时候,如果我们选择使用U盘启动PE,然后通过U盘来装系统,当PE正常运行,这个时候,你拔掉U盘,你觉得你的电脑会黑屏关机吗?答案是不会的,我们确实用U盘来启动了,但是U盘里的PE并没有运行在U盘上,而是读到了内存,所以当你把U盘拔掉,电脑并不会关机,是不是没试过?那就赶快试试吧?以后再有人需要装系统的时候,你就可以展示你的“祖传装系统”手艺了。
1.4 Java访问磁盘文件
我们磁盘中唯一最小描述就是文件,也是操作系统和磁盘驱动器交互的最小单元。值得注意的是,Java创建File对象时,不会关注这个对象是否存在,就好像我们会存很多人的电话号码,但是不会逐个校验每个电话号码是否能打通。
2.网络I/O
前几篇已经介绍了网络传输的部分内容,这里就介绍一下影响网络传输的因素:
- 带宽
- 传输距离
- TCP拥塞