Java知识点–IO流(下)
- 一、节点流和处理流
- 1️⃣基本介绍
- 2️⃣节点流和处理流一览图
- 3️⃣节点流和处理流的区别和联系
- 4️⃣处理流的功能主要体现在以下两个方面:
- 二、处理流 — BufferedReader 和 BufferedWriter
- 1️⃣使用BufferedReader读取文本文件
- 2️⃣使用BufferedWriter将 “hello”,写入文件中
- 3️⃣使用BufferedReader 和 BufferedWriter完成文本文件拷贝
- 三、处理流 — BufferedInputStream 和 BufferedOutputStream
- 1️⃣使用BufferedInputStream 和 BufferedOutputStream完成图片的拷贝
- 四、对象流 — ObjectInputStream 和 ObjectOutputStream
- 1️⃣看一个需求
- 2️⃣序列化和反序列化
- 3️⃣对象流介绍
- 4️⃣使用ObjectOutputStream序列化基本数据类型和Dog对象
- 5️⃣使用ObjectInputStream反序列化恢复数据
- 6️⃣注意事项和细节说明
- ✨五、标准输入输出流
- 六、转换流 — InputStreamReader 和 OutputStreamWriter
- 1️⃣引入转换流的原因
- 2️⃣介绍InputStreamReader 和 OutputStreamWriter
- 3️⃣用InputStreamReader读取文件,指定gbk编码
- 4️⃣用OutputStreamWriter写入文件,指定gbk编码
- 七、打印流 — PrintStream 和 PrintWriter
- 1️⃣用PrintStream写入数据
- 2️⃣用PrintWriter写入数据
- 八、Properties 类
- 1️⃣看一个需求
- 2️⃣读取配置文件
- 3️⃣写入配置文件
一、节点流和处理流
1️⃣基本介绍
节点流:只能从特定的数据源读写数据,例如:访问文件用FileReader
,访问数组用CharArrayReader
,访问管道用PipedReader
,访问字符串用StringReader
。
处理流:也叫包装流,为程序提供更为强大的读写功能,也更加灵活,如BufferedReader
,BufferedWriter
,将节点流封装起来,可以访问文件,数组,管道,字符串等。
2️⃣节点流和处理流一览图
3️⃣节点流和处理流的区别和联系
1.节点流是底层流/低级流,直接跟数据源相接。
2.处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
3.处理流(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连。
4️⃣处理流的功能主要体现在以下两个方面:
1.性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
2.操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便。
二、处理流 – BufferedReader 和 BufferedWriter
BufferedReader
和 BufferedWriter
属于字符流,是按照字符来读写数据的,关闭处理流时,只需关闭外层流即可。
1️⃣使用BufferedReader读取文本文件
import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;public class Exercise08 { public static void main(String[] args) throws IOException { //1.确定文件路径 String filePath = "e:\\story1.txt"; //2.引入BufferedReader BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath)); //3.定义读取行数 String readLen = null; //4.按行读取,当返回 null 时,表示文件读取完毕 while ((readLen = bufferedReader.readLine()) != null){ System.out.println(readLen); } //5.关闭外层流,只需要关闭 BufferedReader,因为底层会自动的去关闭节点流 bufferedReader.close(); }}
2️⃣使用BufferedWriter将 “hello”,写入文件中
import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;public class Exercise09 { public static void main(String[] args) throws IOException { //1.确定文件路径 String filePath = "e:\\a9.txt"; //2.引入BufferedWriter BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath)); //3. 写入"hello" bufferedWriter.write("hello"); //4.关闭外层流 bufferedWriter.close(); }}
3️⃣使用BufferedReader 和 BufferedWriter完成文本文件拷贝
import java.io.*;public class Exercise10 { public static void main(String[] args) throws IOException { //1. BufferedReader 和 BufferedWriter 是按照字符操作 //2. 不要去操作 二进制文件[声音,视频,doc, pdf], 可能造成文件损坏 String filePath = "e:\\a9.txt"; String newFilePath = "e:\\a10.txt"; BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath)); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(newFilePath)); String s; //说明: readLine 读取一行内容,但是没有换行 while ((s = bufferedReader.readLine()) != null){ //每读取一行,就写入 bufferedWriter.write(s); //插入一个换行 bufferedWriter.newLine(); } //关闭流 bufferedReader.close(); bufferedWriter.close(); }}
三、处理流 – BufferedInputStream 和 BufferedOutputStream
BufferedInputStream
和 BufferedOutputStream
属于字节流,是按照字节来读写数据的,关闭处理流时,只需关闭外层流即可。
1️⃣使用BufferedInputStream 和 BufferedOutputStream完成图片的拷贝
import java.io.*;//字节流可以操作二进制文件,也可以操作文本文件public class Exercise11 { public static void main(String[] args) throws IOException { String filePath = "e:\\3.jpg"; String newFilePath = "e:\\4.jpg"; BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath)); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(newFilePath)); byte[] arr = new byte[1024]; int readLen = 0; //当返回 -1 时,就表示文件读取完毕 while ((readLen = bufferedInputStream.read(arr)) != -1) { bufferedOutputStream.write(arr,0,readLen); } //关闭流 , 关闭外层的处理流即可,底层会去关闭节点流 bufferedInputStream.close(); bufferedOutputStream.close(); }}
四、对象流 – ObjectInputStream 和 ObjectOutputStream
1️⃣看一个需求
1.将int num=100这个 int数据保存到文件中,注意不是 100 数字,而是 int 100,并且,能够从文件中直接恢复 int 100
2. 将 Dog dog = new Dog(“小黄”,3)这个 dog对象 保存到 文件中,并且能够从文件恢复.
3.上面的要求,就是能够将 基本数据类型 或者 对象 进行 序列化
和 反序列化
操作
2️⃣序列化和反序列化
1.序列化
就是在保存数据时,保存数据的值和数据类型
2.反序列化
就是在恢复数据时,恢复数据的值和数据类型
3.需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:
Serializable
//这是一个标记接口,没有方法
Externalizable
//该接口有方法需要实现,因此我们一般实现上面的 Serializable接口
3️⃣对象流介绍
功能:提供了对基本类型或对象类型的序列化和反序列化的方法
ObjectOutputStream
提供 序列化
功能
ObjectInputStream
提供 反序列化
功能
4️⃣使用ObjectOutputStream序列化基本数据类型和Dog对象
import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;import java.io.Serializable;public class Exercise12 { public static void main(String[] args) throws IOException { String filePath = "e:\\a12.txt"; ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath)); objectOutputStream.writeInt(100); objectOutputStream.writeBoolean(true); objectOutputStream.writeChar('a'); objectOutputStream.writeDouble(12.5); objectOutputStream.writeUTF("hello"); objectOutputStream.writeObject(new Dog("tom", 3)); objectOutputStream.close(); }}public class Dog implements Serializable { private String name; private int age; public Dog(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; }}
5️⃣使用ObjectInputStream反序列化恢复数据
import java.io.FileInputStream;import java.io.IOException;import java.io.ObjectInputStream;public class Exercise13 { public static void main(String[] args) throws IOException, ClassNotFoundException { String filePath = "e:\\a12.txt"; ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath)); System.out.println(objectInputStream.readInt()); System.out.println(objectInputStream.readBoolean()); System.out.println(objectInputStream.readChar()); System.out.println(objectInputStream.readDouble()); System.out.println(objectInputStream.readUTF()); System.out.println(objectInputStream.readObject()); objectInputStream.close(); }}
6️⃣注意事项和细节说明
1)读写顺序要一致
2)要求序列化或反序列化对象 ,需要 实现 Serializable
3)序列化的类中建议添加SerialVersionUID
,为了提高版本的兼容性
4)序列化对象时,默认将里面所有属性都进行序列化,但除了static
或transient
修饰的成员
5)序列化对象时,要求里面属性的类型也需要实现序列化接口
6)序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
✨五、标准输入输出流
\ | 类型 | 默认设备 |
---|---|---|
System.in 标准输入 | InputStream | 键盘 |
System.out 标准输出 | PrintStream | 显示器 |
六、转换流 – InputStreamReader 和 OutputStreamWriter
1️⃣引入转换流的原因
1、IDEA中默认以UTF-8编码续取文件。
2、如果文件是以gbk编码保存的,以UTF-8读取可能会出现乱码,因此需要转换流。
3、转换流可以将字节流转换成字符流。
4、在处理纯文本数据时,使用字符流效率更高,也可以解决中文问题,所以建议将字节流转换成字符流。
5、可以在使用时指定编码格式。
2️⃣介绍InputStreamReader 和 OutputStreamWriter
1. InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成(转换)Reader(字符流)
2.OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
3️⃣用InputStreamReader读取文件,指定gbk编码
import java.io.*;public class Exercise14 { public static void main(String[] args) throws IOException { String filePath = "e:\\a10.txt"; //1. 把 FileInputStream 转成 InputStreamReader //2. 指定编码 gbk InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(filePath), "gbk"); //3. 把 InputStreamReader 传入 BufferedReader BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String s; //4. 读取 while ((s = bufferedReader.readLine()) != null){ System.out.println(s); } //5. 关闭外层流 bufferedReader.close(); }}
4️⃣用OutputStreamWriter写入文件,指定gbk编码
import java.io.*;public class Exercise15 { public static void main(String[] args) throws IOException { String filePath = "e:\\a15.txt"; OutputStreamWriter gbk = new OutputStreamWriter(new FileOutputStream(filePath), "gbk"); gbk.write("hello,world"); gbk.close(); }}
七、打印流 – PrintStream 和 PrintWriter
打印流只有输出流,PrintStream是字节流,PrintWriter是字符流。
1️⃣用PrintStream写入数据
import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintStream;public class PrintStream_ { public static void main(String[] args) throws FileNotFoundException { String filePath = "e:\\m1.txt"; PrintStream printStream = new PrintStream(new FileOutputStream(filePath)); printStream.println("hello"); printStream.close(); }}
2️⃣用PrintWriter写入数据
import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;public class PrintWriter_ { public static void main(String[] args) throws IOException { String filePath = "e:\\t2.txt"; PrintWriter printWriter = new PrintWriter(new FileWriter(filePath)); printWriter.println("肌肤光滑"); printWriter.close(); }}
八、Properties 类
1️⃣看一个需求
1、XX·properties表示配置文件,可以存放用户名,密码等
2、如果用户名,密码写在源程序中,用户改密码就需要改源码,很不方便,因此需要配置文件我们可以通过程序读取和写入配置文件
3、在src目录下定义 mysql.properties 配置文件
ip=192.168.100.100user=rootpwd=12345
2️⃣读取配置文件
import java.io.FileReader;import java.io.IOException;import java.util.Properties;public class Exercise16 { public static void main(String[] args) throws IOException { Properties properties = new Properties(); properties.load(new FileReader("src\\mysql.properties")); properties.list(System.out); String user = properties.getProperty("user"); System.out.println(user); }}
3️⃣写入配置文件
import java.io.FileWriter;import java.io.IOException;import java.util.Properties;public class Exercise17 { public static void main(String[] args) throws IOException { Properties properties = new Properties(); properties.setProperty("name","tom"); properties.setProperty("sex","male"); properties.setProperty("age","30"); properties.store(new FileWriter("src\\1.properties"), null); }}
1.properties
sex=malename=tomage=30