一、IO流是什么
惯例引用百科的回答
流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出 [1] .
我对IO流的理解就是"你的程序和系统之间读写文件的操作就是IO操作,和系统之间读写用的东西就是IO流"。
JAVA IO流就是JAVA程序和操作系统之间通信用的方法。
二、JAVA IO系统脑图
给大家看下JAVA IO的脑图
自己画的JAVA的脑图,如果有需要原文件的去我公众号,发送:JAVA IO,就可以得到脑图的原文件了,带黄色文件夹标注的是我自己写的注释嗷。
什么你还不知道我公众号,微信搜索,千珏,是千珏(jue)就可以关注到我了。
可以看下我别的文章2019数据分析师必备资源
三、JAVA IO流详解
在这里由于篇幅的原因我只讲解JAVA IO流中的字节流和字符流,别的就等以后再写,比如:NIO AIO BIO这些,以后有时间抽出时间出来写一篇,要是想看的记得点个关注哦。
下面进入正题:
3.1 字节流和字符流的区别
字节流和字符流操作的本质区别只有一个:字节流是原生的操作,字符流是经过处理后的操作。
画个图,字节流在操作时不会用到缓冲区,也就是不会用到内存,文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件,看下图:为什么要有字符流而不直接用字节流呢?
我相信有些读者心里肯定要问这个问题,我刚开始学习的时候也想过这个问题,为什么不直接用字节流解决呢,还非要搞个字符流出来呢。
我的理解就是字节流处理多个字节表示的东西的时候有可能会出现乱码的问题,比如汉字,用字节流读取的时候有可能因为一位字节没有读到就变成了乱码,字符流呢就完美解决了这个问题,字符流你们可以这样理解,字节流和编码表的组合就是字符流。因为有了编码表所以可以确定这个汉字有多少个字节,这样字节流就可以根据位数准确的读写汉字了。
以上纯为个人理解,如有不对的地方请在评论区给我留言哦。
3.2 字节流
字节流顾名思义就是通过字节直接操作字符,更底层一些。
字节流最基础的两个类就是 InputStream和 OutputStream ,根据这两个派生而来类都含有 read()和 write() 的基本方法,用于读写单个字节或者字节数组。
3.2.1 InputStream 和 OutputStream类
InputStream类是一个抽象类 ,是所有字节输入流类的父类。
OutputStream类是一个抽象类,是所有字节输出流的父类
InputStream的常见子类有:
FileInputStream:看这个名字就知道用于从文件中读取信息。
ByteArrayInputStream: 字节数组输入流,
ObjectInputStream:序列化时使用 一般和ObjectOutputStream一起使用
FilterInputStream: 过滤输入流,为基础的输入流提供一些额外的操作。
OutputStream的常见子类有:
FileOutPutStream: 文件输出流对文件进行操作
ByteArrayOutputStream: 字节数组输出流
ObjectOutputStream: 序列化时使用 一般和OjbectInputStream一起使用
FilterOutputStream:过滤输出流,为基础的输出流提供一些额外的操作。
我们一个一个过要不然怎么能叫一文带你看懂JAVA IO流了呢,那样不就是标题党了吗[滑稽]。
3.2.1.1 FileInputStream 和 FileOutPutStream类
1) FileInputStream 和 FileOutPutStream概念
FileInputStream是文件字节输入流,就是对文件数据以字节的方式来处理,如音乐、视频、图片等。
FileOutPutStream是文件字节输出流,
2)FileInputStream里面的方法
//通过文件的名字来创建一个对象
public FileInputStream(String name) throws FileNotFoundException{}
//通过File对象来创建一个对象
public FileInputStream(File file) throws FileNotFoundException{}
/**
* 通过FileDescriptor来创建一个对象
* FileDescriptor是一个文件描述符号
* 有in,out,err三种类型
* in:标准输入描述符,out:标准输出的描述符,err:标准错误输出的描述号
*/
public FileInputStream(FileDescriptor fdObj){}
//打开指定的文件进行读取 ,是java和c之间进行操作的api 我们并不会用到
private native void open0(String name){}
//打开指定的文件进行读取,我们并不会用到 因为在构造方法里面帮我们打开了这个文件
private void open(String name){}
//从输入流中读取一个字节的数据,如果到达文件的末尾则返回-1
public int read() throws IOException{}
//读取一个字节数组
private native int readBytes(byte b[], int off, int len) throws IOException;
private native int read0() throws IOException;
//从输入流中读取b.length的数据到b中
public int read(byte b[]) throws IOException{}
//从输入流中读取off到len之间的数据到b中
public int read(byte b[], int off, int len) throws IOException{}
//跳过并丢弃输入流中的n个数据
public long skip(long n) throws IO