IO流基础知识点汇总

java的io流体系可以有几个方向去总结:

第一个:总体分为字节流和字符流

第二个:总体分为输出流和输入流

所以以上两类进行随即组合一共有四种大类:字节输入流、字节输出流、字符输入流、字符输出流。

基础须知!

讲到java中io流,就要知道什么是流这样一个基本概念:

  1. 首先java程序的输入输出的操作都是以“流”的方式进行的(就和管道一样)
  2. JDK内提供了各种各样的“流”用以获取不同类型的数据。(这点很关键,为啥?因为下面文章几乎都是就介绍2java的各种流的类)java中的流类型都在java.io包中,引用需要    导入。
  3. 数据源:提供原始数据的原始媒介例如常见 的有:数据库、文件、其他程序、内存、网络连接(即网上的资源)、io设备(举个简单的例子,你的键盘)
  4. 数据源像一个水箱,我们的io流就像连接这个水箱和我们程序之间的水管中的水流,程序是我们的最终用户,流是一个抽象的概念,是一连串连续动态的数据集合。

正题开始!

一下内容均为鑫鑫怪本人所总结,有误的地方,请“猛烈的攻击我”。在评论区指出,万分感谢

根据上文所总结的咱们io流总的分为四个大类

字节输入流(InputStream)

字节输出流(OutputStream)

字符输入流(Reader)

字符输出流(Writer)

  这里你或许会问为啥要分这么多,咱们计算机的世界存储的都是二进制的数据,直接用字节不就好了嘛?这里就涉及一个读取效率的问题,我们知道在我们的生活中除了字节文件,文件的文件形式最多的是什么当然就是文本文件了,如果你一个一个字节的去处理数据,数据量一大,那不就太慢了嘛?所以字符流就很好的解决了这个问题,但值得注意的是,字符流只能用在纯文本的的操作上,怎么说呢,这东西我觉得有用的时候贼香,不好用的时候有点鸡肋,所以一般用字节流,但注意!只要纯文本的情况下,就必须要用字符流,这玩意的在这方面的效率还是高的。

在编写程序的使用IO流时注意在写入时都加一个flush()方法。不然有的会写入不成功。

 

以上四类均是抽象类,也就是说不能去实例化他们只能使用他们的实例,未来工作的时候也是这样干的(我还没工作,大佬说的)

 

下面,我根据数据源的不同或者功能的不同来大概说一下他们各个子类的常用形式,之所以不按照上面四类来说,是因为我觉得会乱,我以前就乱过,回头看才知道的更清楚的。

这里有必要说明一下:输入流输出流的定义都是从程序开始的,外面的数据到程序我们叫输入流,程序的数据到外面的我们叫输出流

文件字节流

FileInputStream:文件字节输入流

FileOutputStream:文件字节输出流

简单讲解:很明显文件字节流的数据源是文件,然后他的类型是字节流。

构造方法:

 

FileInputStream构造方法:

io流可以分为 java io流分为几种_字符流

 

 

 

 

FileOutputStream构造方法:

io流可以分为 java io流分为几种_输出流_02

 

 

 

 

常用方法:就一个read和write方法,具体,查一查API文档说的比俺详细。包括他们的重写。

 

 

 

 

缓冲字节流/缓冲字符流

这是什么?

缓冲流的作用其实很好理解就是“水管升级”,怎么说,就是为了让你的流 “更高”、“更强”、“更大”(嘿嘿,这是夸张的手法,你懂我的意思就行)他提高了读取的效率(提高一倍),在有的地方也将它做为一个包装流来用

在java中缓冲流的实现类是:

缓冲字节流

BufferedInpuStream、BufferedOutputStream

缓冲字符流

BufferedReader、BufferedWriter

 

各自的构造方法:

io流可以分为 java io流分为几种_字符流_03

 

 

io流可以分为 java io流分为几种_io流可以分为 java_04

 

 

常用方法:也是read和write。

io流可以分为 java io流分为几种_io流可以分为 java_05

 

 

 

打印流

PrintStream:字节打印流

PrintWriter:字符打印流

可实现将基本数据类型格式化为字符串输出,这里提示!打印流只有输出打印流没有输入打印流,千万别问,问就暴露智商了(嘿嘿,以前我问过)

构造方法:

 

io流可以分为 java io流分为几种_字符流_06

 

 

 

数据流

DataInputStream:数据输入流

DataOutputStream:数据输出流

说明:这个流提供了可以存取所有java基础类型数据和String的方法,只要关闭上层流即可。

这里需要注意一下:数据流只有字节流没有字符流,你问为什么?那我就问问你,数据类型难道只有纯文本的那些嘛?

构造方法:

io流可以分为 java io流分为几种_输出流_07

 

 

io流可以分为 java io流分为几种_字节流_08

 

 

 

对象流

ObjectOutputStream:对象输出流

ObjectInputStream:对象输入流

说明一下:为什么有这个对象流?以我的观点,在面向对象的编程思想下,我们开发者大多数时候面对的不是一个一个原子性的数据类型,,更多的是面对一个对象或者一个个类去使用在程序中,所以对一个封装了很多数据类型的对象来说,需要有这么个东西适合他自身情况的管子去“运输”他。重点:如果你想让一个自定义的类有这样一个可以被“运输”特性就必须让他序列化,在Java中其实就是让这个类实现Serializable,这个接口有点好玩,他是Java中一个唯一一个什么方法都不用实现的接口。

 

在输出对象的时候又被称为对象的序列化,输入对象又叫反序列化。

 

最后一个转换流:就是将字节流转成字符流的“管子”

OutputStreamWriter含有方法如下:

  1. flsh():刷新该流的缓冲。
  2. close():关闭此流,关闭前需要刷新。
  3. write():write(char[] ,int offset ,int length),写入字符数组的某一部分。

 

InputStreamReader含有方法如下:

  1. close():关闭此流。
  2. read():读取单个字符。

 

这里有个小知识,如果你序列化的对象里面还有一个对象,这个对象也需要序列化,不然跑程序的时候会报错。对对象进行序列化的时候要加上版本号,避免一些其他情况的发生,例如在你序列化好一个对象后,使用了对象流,第一次没什么问题,但在之后你对对象进行修改之后,就会程序就会报错,如果添加了序列版本号之后就不会有这些问题了,另外对象在序列化的时候被static修饰的成员变量和被transient修饰的变量不可被读。

 

其实io流的实现和使用过程和设计模式中“装饰模式”是一个机制的,这里我就不展开装饰模式了,我也了解不多,有兴趣,自己查去吧。