IO流
- 用于读写文件中的数据(可以读写文件或网络中的数据)
- I:input
- O:output
1.IO流的分类
1 流的方向
- 输入流(读取:程序 -> 文件)
- 输出流(写出:文件 -> 程序)
2操作文件类型
- 字节流(所有类型的文件)
- 字符流(纯文本文件)
纯文本文件:Windows系统自带的记事本可打开并读懂的文件;txt、md、xml、lrc文件等
一、普通流
1、FileOutputStream
- 操作本地文件的字节输出流,可以把程序中的数据写到本地文件中
- 书写步骤
1、创建字符流对像
- 细节1:参数是字符串表示的路径或者File对象都是可以的
- 细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。
- 细节3:如果文件已经存在,则会清空文件
2、写数据
- 细节: write方法的参数是整数,但是实际上写到本地文件中的是整数在ASCII上对应的字符
3、释放资源
- 细节:每次使用完流之后都要释放资源
-
FileOutputStream写数据的三种方式
2、FileIntputStream
- 操作本地文件的字节输出流,可以把本地文件中的数据写到程序中
- 书写步骤
1、创建字节输入流对象
- 细节1:如果文件不存在,就直接报错
2、读取数据
- 细节1:一次读一个字节,读出来的是数据在ASCII上对应的数字
- 细节2:读到文件末尾了,read方法返回-1
3、 释放资源
- 细节1:每次使用完流必须要释放资源
- FileIntputStream的循环读取
package org.example;
import java.io.FileInputStream;
import java.io.IOException;public class Outer {public static void main(String[] args) throws IOException {FileInputStream fi = new FileInputStream("a.txt");int b;while((b = fi.read()) != -1){System.out.println((char)b);}fi.close();}
}
- FileIntputStream一次读取多个字节
注:一次读一个字节数组的数据,每次读取会尽可能把数组装满
3、FileWriter
-
构造方法
- 成员方法
- 书写细节
1、创建字符输出流对象
- 细节1:参数是字符串表示的路径或者File对象都是可以的
- 细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
- 细节3:如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关
2、写数据
- 细节: 如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符
3、释放资源
- 细节:每次使用完流之后都要释放资源
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;public class WriteFileExample {public static void main(String[] args) {String content = "这是要写入文件的内容";try (Writer writer = new FileWriter("example.txt")) {writer.write(content);} catch (IOException e) {e.printStackTrace();}}
二、缓冲流
1、字节缓冲流
- 底层远离:建缓冲区(长度为8192的字节数组)
- 方法名称
package org.example;
import java.io.*;public class Outer {public static void main(String[] args) throws IOException {//1.创建缓冲流的对象BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt"));//2.循环读取并写到目的地int b;while ((b = bis.read()) != -1) {bos.write(b);//3.释放资源bos.close();bis.close();}}
}
2.字符缓冲流
- 原理解析
1、创建字符输入流对象
- 底层:关联文件,并创建缓冲区(长度为8192的字节数组)
2、读取数据
- 底层:1.判断缓冲区中是否有数据可以读取
- 2.缓冲区没有数据:就从文件中获取数据,装到缓冲区中,每次尽可能装满缓冲区,如果文件中也没有数据了,返回-1
- 3.缓冲区有数据:就从缓冲区中读取。
空参的read方法:一次读取一个字节,遇到中文一次读多个字节,把字节解码并转成十进制返回
有参的read方法:把读取字节,解码,强转三步合并了,强转之后的字符放到数组中
- 构造方法
- 字符缓冲流的特有方法
package org.example;
import java.io.*;public class Outer {public static void main(String[] args) throws IOException {//1.创建字符缓冲输入流的对象BufferedReader br = new BufferedReader(new FileReader("a.txt"));//2.读取数据//细节://readLine方法在读取的时候,一次读一整行,遇到回车换行结束//但是他不会把回车换行读到内存当中String line1 = br.readLine();System.out.println(line1);String line2 = br.readLine();System.out.println(line2);//3.释放资源br.close();}
}
循环获取:
三、 转换流(字符流和字节流之间的桥梁)
- 字符转换输入流:InputStreamReader
- 字符转换输出流:0utputStreamWriter
- 作用:
- 指定字符集读写数据(JDK11之后已淘汰)
- 字节流想要使用字符流中的方法了
package org.example;
import java.io.*;public class Outer {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("a.txt");InputStreamReader isr =new InputStreamReader(fis);BufferedReader br = new BufferedReader(isr);String str = br.readLine();System.out.println(str);br.close();}
}
四、序列化/对象操作输出流
- 可以把Java的对象写到本地文件中
package org.example;
import java.io.*;public class Outer {public static void main(String[] args) throws IOException {//1.创建对象Student stu = new Student("zhangsan", 23);//2.创建序列化流的对象/对象操作输出流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));//3.写出数据oos.writeObject(stu);//4.释放资源oos.close();}
}
反序列化/对象操作输入流
- 可以把序列化到本地文件中的对象,读取到程序中来
序列化流/反序列化流的细节汇总
- ① 使用序列化流将对象写到文件时,需要让Javabean类实现Serializable接口。否则,会出现NotSerializableException异常
- ②序列化流写到文件中的数据是不能修改的,一旦修改就无法再次读回来了
- 序列化对象后,修改了Javabean类,再次反序列化,会不会有问题?会出问题,会抛出InvalidclassException异常;解决方案:给lavabean类添加serialVersionUID(列号、版本号)
- 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?解决方案:给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
五、打印流
- 分类:打印流一般是指:PrintStream,PrintWriter两个类
- 特点1:打印流只操作文件目的地,不操作数据源
- 特点2:特有的写出方法可以实现,数据原样写出
例如:
打印:97 文件中:97
打印:true 文件中:true
- 特点3:特有的写出方法,可以实现自动刷新,自动换行(打印一次数据 =写出+换行+刷新)
1、字节打印流
字节流低层没有缓冲区,开不开自动刷新都一样
package cn.test;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;public class PrintStreamtDemo1 {public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {PrintStream ps = new PrintStream(new FileOutputStream("a.txt"),true,Charset.forName("UTF-8").name());ps.println(97);ps.print(true);ps.printf("%s吃%s","小明","范");ps.close();}
}
2、字符打印流
字符流低层有缓冲区,需要自动刷新可开启
打印流有几种?各有什么特点?
- 有字节打印流和字符打印流两种
- 打印流不操作数据源,只能操作目的地
- 字节打印流:默认自动刷新,特有的println自动换行
- 字符打印流:自动刷新需要开启,特有的println自动换行
六、解压缩流/压缩流
1、解压缩流
2、压缩流