处理流
也叫包装流,是连接在已存在的流(节点流 或 处理流)之上,为程序提供更为强大的读写功能,也更加灵活。
修饰器
处理流对节点流进行包装,使用了修饰器设计模式。
字符处理流
BufferedReader 和 BufferedWriter 属于字符流,是按照字符来读取数据的,操作非文本文件(二进制文件)可能会造成文件损坏。
BufferedReader
示例代码如下:
String filePath = "D:\\my-space\\javase\\han-io\\io\\story.txt";
// 创建处理流
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
// 按行读取,效率高
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
// 关闭流
bufferedReader.close();
BufferedWriter
示例代码如下:
String filePath = "D:\\my-space\\javase\\han-io\\io\\note.txt";
// 创建 BufferWriter
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
bufferedWriter.write("校花好美");
bufferedWriter.close();
拷贝
实现文本代码复制:
String srcFilePath = "D:\\my-space\\javase\\han-io\\io\\note.txt";
String descFilePath = "D:\\my-space\\javase\\han-io\\io\\note2.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(srcFilePath));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(descFilePath));
String line;
while ((line = bufferedReader.readLine()) != null) {
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedWriter.close();
bufferedReader.close();
字节处理流
使用 BufferedOutputSteam 和 BufferedInputStream 完成非文本文件的拷贝:
String srcFilePath = "D:\\my-space\\javase\\han-io\\io\\DOLL2.jpg";
String descFilePath = "D:\\my-space\\javase\\han-io\\io\\DOLL3.jpg";
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFilePath));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(descFilePath));
int readLine;
byte[] data = new byte[1024];
while ((readLine = bufferedInputStream.read(data)) != -1) {
bufferedOutputStream.write(data, 0, readLine);
}
bufferedInputStream.close();
bufferedOutputStream.close();
对象处理流
读写 对象 或 数据的基本数据类型。
序列化和反序列化
- 序列化就是在保存数据时,保存数据的值和数据类型
- 反序列化就是在恢复数据时,恢复数据的值和数据类型
- 对象支持序列化的前提是其类是可序列化的,也就是实现 Serializable 接口 或 Externalizable 接口
ObjectOutputStream
示例代码如下:
String filePath = "D:\\my-space\\javase\\han-io\\io\\data.dat";
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据到 data.dat
objectOutputStream.write(100); // int -> Integer(实现了 Serializable )
objectOutputStream.writeBoolean(true); // boolean -> Boolean(实现了 Serializable )
objectOutputStream.writeChar('a'); // char -> Character(实现了 Serializable )
objectOutputStream.writeUTF("程序员校花"); // String
//保存 dog 对象
objectOutputStream.writeObject(new Dog("大黄", 3));
objectOutputStream.close();
ObjectInputStream
示例代码如下:
String filePath = "D:\\my-space\\javase\\han-io\\io\\data.dat";
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.readUTF());
System.out.println(objectInputStream.readObject().getClass());
objectInputStream.close();
标准输入输出流
编译类型 | 运行类型 | 默认设备 | |
---|---|---|---|
System.in | InputStream | BufferedInputStream | 键盘 |
System.out | PrintStream | PrintStream | 显示器 |
转换流
- 字节流 —> 字符流
- InputStreamReader:Reader 的子类,可以将 InputStream(字节流)转换成 Reader(字符流)
- OutputStreamWriter:Writer 的子类,可以将 OutputStream(字节流)转换为 Writer(字符流)
- 当处理纯文本数据时,使用字符流效率更高,并且可以解决中文问题,因此建议将字节流转换为字符流
InputStreamReader
示例代码如下:
String filePath = "D:\\my-space\\javase\\han-io\\io\\a.txt";
// 把 FileInputStream(字节流) 转成 InputStreamReader(字符流),解决乱码问题
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(filePath), "gbk");
// 把 InputStreamReader 传入 BufferedReader,效率高
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String s = bufferedReader.readLine();
System.out.println(s);
bufferedReader.close();
OutputStreamWriter
示例代码如下:
String filePath = "D:\\my-space\\javase\\han-io\\io\\b.txt";
BufferedWriter bufferedWriter = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(filePath), "utf-8")
);
bufferedWriter.write("程序员校花");
bufferedWriter.close();
打印流
打印流只有输出流,没有输入流。
PrintStream
字节打印流,实例代码如下:
PrintStream out = System.out;
// 默认情况下,PrintStream 输出的位置是显示器
out.println("程序员校花");
// print底层使用的是 writer,因此可以直接调用 writer 进行打印/输出
out.write("校花好美".getBytes());
// 修改打印流输出的位置/设备
System.setOut(new PrintStream("D:\\my-space\\javase\\han-io\\io\\note.txt"));
System.out.println("飞龙在天"); // 打印到指定位置
out.close();
PrintWriter
字符打印流,示例代码如下:
PrintWriter printWriter1 = new PrintWriter(System.out);
printWriter1.println("程序员校花"); //输出到屏幕
PrintWriter printWriter2 = new PrintWriter(new FileWriter("D:\\my-space\\javase\\han-io\\io\\b.txt"));
printWriter2.println("校花好美"); // 输出到指定文件
printWriter1.close(); // flush + 关闭流,将数据写入到文件
printWriter2.close();
Properties
HashTable 的子类,专门用于读写配置文件的集合类。
常用方法:
load
:加载指定的配置文件到 Propertieslist
:将数据显示到指定位置getProperty
:根据键获取值setProperty
:设置键值store
:将 Porperties 的键值对存储到配置文件中,第二个参数为注释信息,即配置文件的第一行
实例代码如下:
Properties properties1 = new Properties();
// 加载指定配置文件
properties1.load(new FileReader("D:\\my-space\\javase\\han-io\\io\\mysql.properties"));
// 把 k-v 显示到控制台
properties1.list(System.out);
// 根据 key 获取对于的值
String user = properties1.getProperty("user");
// 创建配置文件
Properties properties2 = new Properties();
properties2.setProperty("username", "张三"); // 保存时是中文的 Unicode 码值
properties2.setProperty("password", "123456");
properties2.store(new FileOutputStream("D:\\my-space\\javase\\han-io\\io\\mysql2.properties"), null);