IO流
随用随创建!!!!
随用随创建!!!!
随用随创建!!!!
以免数据被覆盖
存储和读取数据的解决方案
I:input O:output
流:像水流一样传输数据
作用:用于读写数据(本地文件,网络)
分类:
- 流的方向:输入流(读取)、输出流(写出)
- 操作文件类型:字节流(所有类型的文件)、字符流(纯文本文件)
IO流的体系
字节流
- InputStream 字节输入流
- FileInputStream 操作本地文件的字节输入流
- 操作本地文件的字节输入流,可以把本地文件中的数据读取到代码中
- 步骤:
- 创建对象
- 如果对象读取的文件不存在,直接报错
- 读数据
- 一次读一个字节,读出来的是ASCLL上对应的数字
- 读到末尾,read会返回-1
- 释放资源
- OutputStream 字节输出流
- FileOutputStream 操作本地文件的字节输出流
- 操作本地文件的字节输出流,可以把程序中的数据写到本地文件中
- 步骤:
- 创建字节流输出对象
- 参数可以是字符串表示的罗京或者File对象都是可以的
- 如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
- 如果文件已经存在,会清空文件内容
- 写数据
- write方法的参数是整数,但是实际上写到文件上的内容是整数在ASXII码上对应的字符
- 释放资源
- 每次使用完流后都要释放资源,解除资源的占用
public static void main(String[] args) throws IOException {
//创建对象
FileOutputStream fos = new FileOutputStream("E:\\idea-work\\work\\a.txt");
//写出数据
fos.write('s');
//释放资源
fos.close();
}
- 写数据的三种方式:
- write(int b) 一次写一个字节数据
- write(byte[] b) 一次写一个字节数组数据
- write(byte[] b,int off , int len) 一次写一个字节数组的部分数据
- 可以创建一个字节数组来节省读取和写入的时间,一般情况创建1024的整数倍大小的数组,如果文件较大,一般创建5-10M的数组长度
public static void main(String[] args) throws IOException {
long stime =System.currentTimeMillis();//开始执行时获取时间
FileInputStream fis = new FileInputStream("E:\\idea-work\\work\\movie.mp4");
FileOutputStream fos = new FileOutputStream("E:\\idea-work\\jichu\\jichuyufa\\copy.mp4");
/*int b;
while ((b=fis.read())!=-1){
fos.write(b);
} //该程序执行时间为22秒
*/
int b;
byte[] bytes = new byte[1024*1024*5];
while ((b=fis.read(bytes))!=-1){
fos.write(bytes,0,b);
}
//优化后执行时间为9毫秒
fos.close();
fis.close();
long etime =System.currentTimeMillis();//结束后获取时间
System.out.println(etime-stime);//得出程序执行时间
}
字符集
- ASCLL (英文)
- GBK (英文 中文) 国家标准字符集 系统显示ANSI
- (英文规则 一个字节)不足8位,前面补0
- (汉字规则 两个字节)高位字节二进制一定以1开头,转成十进制是一个负数
- Unicode (英文 中文) 国际标准字符集
- UTF-16编码规则:用2-4个字节保存
- UTF-32编码规则:固定4字节保存
- UTF-8编码规则:用1-4个字节保存 英文字母1个字节,简体中文3个字节
- 表示方法0xxxxxxx(ASCLL) 1110XXXX 10XXXXXX 10XXXXXXX(中文)
乱码解决方式:
- 不要用字节流读取文本文件
- 编码解码时使用同一个码表,同一个编码规则
java中编码解码:
- 编码 getBytes(参数) 定义参数指定方式编码,没有参数表示默认
- 解码 String(bytes,参数) 定义参数指定方式解码,没有参数表示默认
字符流
字符流的底层其实是字节流
- 特点
- 输入流:一次读一个字节,遇到中文时,一次读多个字节
- 输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
- Reader 字符输入流
- FileReader:操作本地文件的字符输入流
- 创建对象
- FileReader() 参数可以为文件路径或者字符串
- 底层原理
关联文件,并创建缓冲区
- 读取数据
- read() 读取一个或多个,读到末尾返回-1
- 一次读取一个字节,遇到中文一次读取多个
- 读取数据解码并转成十进制
- 底层原理
- 判断缓冲区有没有数据可以读取
- 缓冲区没有数据,就冲文件尽可能多的读取数据放入缓冲区中,如果文件也没数据时返回-1
- 缓冲区中有数据,就冲缓冲区中读取数据
- 释放资源
- Writer 字符输出流
- FileWriter:操作本地文件的字符输出流
- FileWriter(file,续写开关) 创建输出流关联本地文件
- writer()写出一个字符、一个字符串或者一个数组
- 创建对象
- 底层:创建缓冲区
- 写出数据
- 底层:
- 先写到缓冲区,当缓冲区满后自动写入目的文件
- 使用flush可以手动保存到文件中
- 关流之前会扫描缓冲区中有没有数据,如果有自动将数据全部写入目标文件后再断开连接
- 调用flush后可以继续写,调用close后就不能继续写数据了
- 释放资源
缓冲流
- 字符缓冲流
BufferedReader(Reader r)
readLine()读一整行数据
BufferedWriter(Writer r)
newLine() 跨平台换行(window、Linux不同平台要求换行符不一致)
- 字节缓冲流
把基本流帮装成高级流:
BufferedInputStream( InputSteam is)
BufferedOutputStream( OutputSteam os)
- 缓冲流自带长度为8192的缓冲区
- 可以显著提高字节流的读写性能
- 对于字符流提升不明显,但是为其提供特有的两个方法
转换流
属于字符流的
是字符流的字节流中间的桥梁
InputStreamReader(转换输入流)
OutputStreamWriter(转换输出流)
作用:字节流中想要使用字符流中的方法了
序列化流
高级流,用来包装普通流,属于字节流的一种,负责输出数据,与之相反的是反序列流,负责输入数据。
序列化流:objectOutputStream
反序列化流:objectInputStream
序列化流
也叫对象操作输出流
可以把Java中的对象写到本地文件中
使用方法:
- objectOutputStream(OutputStream out) 把基本流包装成高级流
- writeObject( object obj) 把对象序列化(写出)到文件中
反序列化流
也叫对象操作输入流
可以把序列化到本地文件中的对象,读取到程序中
使用方法:
- objectInputStream(InputStream In) 把基本流变成高级流
- readObject() 把序列化到本地文件中的对象,读取到程序中来
注意事项
- 写出时需要实现Serializable接口,不然会报错
- 序列化流写到文件中的数据是不能修改的,一旦修改就无法再次读回来
- 序列化到本地文件中对象后,不能修改实现Serializable接口类的代码,否者就会 改版本号,再进行反序列化时因为版本号不同就会出现错误
解决方法:可以进行一个版本号的统一就不会出现该情况发生
private static final long serialVersionUID = 1L; //定义一个版本号
- 如果不想把对象的某个属性序列化(写)到文件中,使用瞬态关键字transient就不会序列化(写)到文件中了
private transient int age;
打印流
高级流,用来包装基本流的,打印流只能写,不能读
- PrintStream 字节打印流
- PrintWriter 字符打印流
特点:
- 打印流自能操作文件的目的地,不能操作数据源(只能写,不能读)
- 特有的写出方法,可以实现数据的原样写出
- 特有的写出方法,可以实现自动刷新、自动换行
字节打印流
创建对象:PrintStream(OutputStream/File/String ) 关联字节输出流/文件/文件路径 没有缓冲区
方法:
- write(int b) 常规方法,将指定字节写出
- println(Xxx xx) 特有方法,打印任意数据,自动换行(没有ln就不自动换行)
- printf(String format , Object… args) 特有方法,带有占位符的打印语句,不换行
字符打印流
字符打印流底层有缓冲区,想要自动刷新需要手动开启
创建对象:PrintWrite(Write/File/String ) 关联字节输出流/文件/文件路径
方法:
- write(…) 常规方法,写出字节或者字符串
- println(Xxx xx) 特有方法,打印任意数据,自动换行(没有ln就不自动换行)
- printf(String format , Object… args) 特有方法,带有占位符的打印语句,不换行
解压缩流/压缩流
- 解压缩流
把每一个ZipEntry按照层级拷贝到本地另一个文件中 - 压缩流
把每一个文件/文件夹看成ZipEntry对象放到压缩包里面
工具包
Commons - io
作用:提高IO流的开发效率
下载官网路径:Commons IO – 下载 Apache Commons IO
下载完后加压就能看见commons-io-2.11.0.jar包了
使用步骤:
- 在项目中创建lib包
- 将commons-io-2.11.0.jar包复制粘贴到lib包中
- 右键点击commons-io-2.11.0.jar包,选择Add as Library ->点击OK
- 在类中导包使用