前言:在之前的面试中,每每问到关于Java I/O 方面的东西都感觉自己吃了大亏..所以这里抢救一下..来深入的了解一下在Java之中的 I/O 到底是怎么回事..文章可能说明类的文字有点儿多,希望能耐心读完..
什么是 I/O?学习过计算机相关课程的童鞋应该都知道,I/O 即输入Input/ 输出Output的缩写,最容易让人联想到的就是屏幕这样的输出设备以及键盘鼠标这一类的输入设备,其广义上的定义就是:数据在内部存储器和外部存储器或其他周边设备之间的输入和输出;
我们可以从定义上看到问题的核心就是:数据/ 输入/ 输出,在Java中,主要就是涉及到磁盘 I/O 和网络 I/O 两种了;
简单理解Java 流(Stream)通常我们说 I/O 都会涉及到诸如输入流、输出流这样的概念,那么什么是流呢?流是一个抽象但形象的概念,你可以简单理解成一个数据的序列,输入流表示从一个源读取数据,输出流则表示向一个目标写数据,在Java程序中,对于数据的输入和输出都是采用 “流” 这样的方式进行的,其设备可以是文件、网络、内存等;
流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流。
可以将流想象成一个“水流管道”,水流就在这管道中形成了,自然就出现了方向的概念。
“流”,代表了任何有能力产出数据的数据源对象或有能力接受数据的接收端对象,它屏蔽了实际的 I/O 设备中处理数据的细节——摘自《Think in Java》
参考资料:深入理解 Java中的 流 (Stream):https://www.cnblogs.com/shitouer/archive/2012/12/19/2823641.html
Java中的 I/O 类库的基本架构I/O 问题是任何编程语言都无法回避的问题,因为 I/O 操作是人机交互的核心,是机器获取和交换信息的主要渠道,所以如何设计 I/O 系统变成了一大难题,特别是在当今大流量大数据的时代,I/O 问题尤其突出,很容易称为一个性能的瓶颈,也正因为如此,在 I/O 库上也一直在做持续的优化,例如JDK1.4引入的 NIO,JDK1.7引入的 NIO 2.0,都一定程度上的提升了 I/O 的性能;
Java的 I/O 操作类在包 java.io下,有将近80个类,这些类大概可以分成如下 4 组:
基于字节操作的 I/O 接口:InputStream 和 OutputStream;
基于字符操作的 I/O 接口:Writer 和 Reader;
基于磁盘操作的 I/O 接口:File;
基于网络操作的 I/O 接口:Socket;
前两组主要是传输数据的数据格式,后两组主要是传输数据的方式,虽然Socket类并不在java.io包下,但这里仍然把它们划分在了一起;I/O 只是人机交互的一种手段,除了它们能够完成这个交互功能外,我们更多的应该是关注如何提高它的运行效率;
00.基于字节的 I/O 操作接口基于字节的 I/O 操作的接口输入和输出分别对应是 InputStream 和 OutputStream,InputStream 的类层次结构如下图:
输入流根据数据类型和操作方式又被划分成若干个子类,每个子类分别处理不同操作类型,OutputStream 输出流的类层次结构也是类似,如下图所示:
这里就不详细解释每个子类如何使用了,如果感兴趣可以自己去看一下JDK的源码,而且的话从类名也能大致看出一二该类是在处理怎样的一些东西..这里需要说明两点:
1)操作数据的方式是可以组合使用的:
例如:
OutputStream out = new BufferedOutputStream(new ObjectOutputStream(new FileOutputStream("fileName"));2)必须要指定流最终写到什么地方:
要么是写到磁盘,要么是写到网络中,但重点是你必须说明这一点,而且你会发现其实SocketOutputStream是属于FileOutputStream下的,也就是说写网络实际上也是写文件,只不过写网络还有一步需要处理,就是让底层的操作系统知道我这个数据是需要传送到其他地方而不是本地磁盘上的;
01.基于字符的 I/O 操作接口