一、IO流:基本流
IO概述
I:intput 输入(读取read) 从其他存储设备 读取数据到 内存中
O:output 输出(写出 write) 从内存 写出数据到 其他存储设备
IO的分类
按照流向分:
输入流:从其他存储设备 读取数据到 内存中的流
字节输入流:顶层父类InputStream—此抽象类是表示字节输入流的所有类的超类
字符输入流:顶层父类Reader—用于读取字符流的抽象类
输出流:从内存 写出数据到 其他存储设备的流
字节输出流:顶级父类OutputStream------此抽象类是表示字节输出流的所有类的超类
字符输出流:顶级父类Writer—用于写入字符流的抽象类
按照类型分:
字节流:以字节为基本单位的流
字节输入流:顶层父类InputStream—此抽象类是表示字节输入流的所有类的超类
字节输出流:顶级父类OutputStream------此抽象类是表示字节输出流的所有类的超类
字符流:以字符为基本单位的流
字符输入流:顶层父类Reader—用于读取字符流的抽象类
字符输出流:顶级父类Writer—用于写入字符流的抽象类
结论:
IO的顶层父类是抽象类,集合的顶级是接口
IO相关的类都是在java.io包,集合相关的类都是在java.util包
二、字节流
1.字节输出流:顶层父类outputStream 抽象类
常用子类:FileOutputStream字节输出流,用来输出数据的
1.1.包:java.io
1.2.概述:用来表示字节输出流
1.3.构造方法
-public FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件。
-public FileOutputStream(String name): 创建文件输出流以指定的名称写入文件。
当你创建一个流对象时,必须传入一个文件路径。
该路径下,如果没有这个文件,会创建该文件。
如果有这个文件,会清空这个文件的数据。
-public FileOutputStream(File file, boolean append): 创建文件输出流以写入由指定的 File对象表示的文件。
-public FileOutputStream(String name, boolean append): 创建文件输出流以指定的名称写入文件。
这两个构造方法,参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示清空原有数据
1.4.常用的成员方法(字节输出流的顶层父类OutputStream)
- public abstract void write(int b) :将指定的字节输出流。一次写一个字节数据到目的地文件
- public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。 写一个字节数组
- public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。写指定长度的字节数组
- public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
- public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
注意:当完成流的操作时,必须调用close方法,释放系统资源。
数据追加续写
- 回车符\r和换行符\n :
- 回车符:回到一行的开头(return)。
- 换行符:下一行(newline)。
- 系统中的换行:
- Windows系统里,每行结尾是 回车+换行 ,即\r\n;—由于换行在字节流中是字符串的形式,需要强制转换为byte类型—使用getbytes方法
- Unix系统里,每行结尾只有 换行 ,即\n;
- Mac系统里,每行结尾是 回车 ,即\r。从 Mac OS X开始与Linux统一。
2.输入字节流:顶层父类InputStream—此抽象类是表示字节输入流的所有类的超类
2.1.常用子类:FileInputStream类
2.2.定义了字节输入流的基本共性功能方法。
- public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
- public abstract int read(): 从输入流读取数据的下一个字节。
一次读取一个字节数据,如果读取到了文件的末尾就返回-1;
- public int read(byte[] b): 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
一次读取一个字节数组---读取到了文件的末尾就返回-1;
注意:close方法,当完成流的操作时,必须调用此方法,释放系统资源
子类FileInputStream类:
1.字节输入流:用来从文件中读取字节。
2.构造方法
- FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
- FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
注意:如果指定的源文件路径不存在,那么就会报文件找不到异常FileNotFoundException
三、字符流:以单个字符为基本单位读写的流,主要用来操作文本文件
1.字符输入流:【Reader】
java.io.Reader抽象类是表示用于读取字符流的所有类的超类,可以读取字节信息到内存中。
它定义了字符输入流的基本共性功能方法。
- public void close() :关闭此流并释放与此流相关联的任何系统资源。
- public int read(): 从输入流读取一个字符。读到数据的末尾返回-1
- public int read(char[] cbuf): 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。读到数据的末尾返回-1
字符输入流的子类:FileReader类
构造方法
- FileReader(File file): 创建一个新的 FileReader ,给定要读取的File对象。
- FileReader(String fileName): 创建一个新的 FileReader ,给定要读取的文件的名称。
当你创建一个流对象时,必须传入一个真实存在的文件路径。类似于FileInputStream 。
传入的数据源文件路径一定要存在,否则会报异常 FileNotFoundException
2.字符输出流【Writer】
java.io.Writer抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。
它定义了字符输出流的基本共性功能方法。
- public abstract void close() :关闭此输出流并释放与此流相关联的任何系统资源。
刷新数据,并且关闭流,关闭流之后该流就不能再使用了
- public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出。
刷新数据,刷新完之后,该流还可以继续使用
- public void write(int c) :写出一个字符。---常用
- public void write(char[] cbuf):将 b.length字符从指定的字符数组写出此输出流。
一次写出一个字符数组
- public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移量 off开始输出到此输出流。--常用
一次写出一个指定长度的字符数组
- public void write(String str) :写出一个字符串。---常用
-write(String str, int off, int len):一次写出一个指定范围的字符串
字符输出流子类:FileWriter 类
构造方法
- FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象。
- FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。
当你创建一个流对象时,必须传入一个文件路径。
该路径下,如果没有这个文件,会创建该文件。
如果有这个文件,会清空这个文件的数据。
- FileWriter(File file, boolean append) 根据给定的 File 对象构造一个 FileWriter 对象。
- FileWriter(String fileName, boolean append) 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。
这两个构造方法,参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示清空原有数据
注意:字符流,只能操作文本文件,不能操作图片,视频等非文本文件。—>即是文本可以看到的文件—不包括乱码
字节流,可以拷贝一切文件
编码问题
gbk编码的中文在内存中占2个字节
utf8编码的中文在内存中占3个字节
idea默认编码为utf8编码
windows默认编码为gbk编码
如果存储数据的编码和解析数据的编码不一致,那么就会出现乱码
使用字节流可能会出现这样的问题
解决方案:需要使用字符流来解决
四、IO异常处理
jdk7之前 标准处理IO异常的代码
JDK7的处理IO流异常的代码:
优化:
JDK7优化后的try-with-resource 语句,该语句确保了每个资源在语句结束时关闭。
所谓的资源(resource)是指在程序完成后,必须关闭的对象
简而言之:就是无须调用close()方法关闭资源,因为会自动关闭资源
try (创建流对象语句,如果多个,使用’;'隔开) {
// 读写数据
} catch (IOException e) {
e.printStackTrace();
}
JDK9的处理
优化:JDK9中try-with-resource 的改进,对于引入对象的方式,支持的更加简洁。被引入的对象,同样可以自动关闭,无需手动close
// 被final修饰的对象
final Resource resource1 = new Resource("resource1");
// 普通对象
Resource resource2 = new Resource("resource2");
// 引入方式:直接引入
try (resource1; resource2) {
// 使用对象
}