Java笔记25
字节缓冲流
- 缓冲流:
BufferedInputStream
/BufferedOutputStream
- 提高IO效率,减少访问磁盘的次数;
- 数据存储在缓冲区中,
flush
是将缓存区的内容写入文件中,也可以直接close
。
BufferedInputStream
- 在目录
d:\\JavaTest\\
下创建一个文本文件aaa.txt
,并给它添加一些数据:
- 使用
BufferedInputStream
读取文件aaa.txt
中的数据:
package com.clown.io;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
/*
使用字节缓冲流读取文件:
BufferedInputStream
*/
public class BufferedInputStreamDemo01 {
public static void main(String[] args) throws Exception {
//1. 创建 BufferedInputStream
FileInputStream fis = new FileInputStream("d:\\JavaTest\\aaa.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
//2. 读取文件
/*
int data = 0;
while ((data = bis.read()) != -1) { //BufferedInputStream有默认的缓冲区(大小为 8192 byte)
System.out.print((char) data);
}
*/
//我们也可以自己创建缓冲区
byte[] buf = new byte[1024]; //自己创建一个缓冲区,大小为 1024 byte
int count = 0;
while ((count = bis.read(buf)) != -1) {
System.out.println(new String(buf, 0, count));
}
//3. 关闭
bis.close();
System.out.println("执行完毕");
}
}
运行结果:
BufferedOutputStream
- 使用
BufferedOutputStream
写入数据到指定文件buffer.txt
中:
package com.clown.io;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
/*
使用字节缓冲流写入文件:
BufferedOutputStream
*/
public class BufferedOutputStreamDemo01 {
public static void main(String[] args) throws Exception {
//1. 创建 BufferedOutputStream
FileOutputStream fos = new FileOutputStream("d:\\JavaTest\\buffer.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//2. 写入文件
for (int i = 0; i < 10; i++) { //写入 10次 "helloworld"
bos.write("helloworld\n".getBytes()); //getBytes(); 将此字符串转换为字节序列,并将结果储存到新的字节数组中
//flush(); 刷新到硬盘
bos.flush();
}
//3. 关闭
bos.close(); //使用 close()方法时,其内部也会调用 flush()方法刷新
System.out.println("执行完毕");
}
}
运行结果:
查看文件:
对象流
-
对象流:
ObjectOutputStream
/ObjectInputStream
- 增强了缓冲区功能。
- 增强了读写8种基本数据类型和字符串功能。
- 增强了读写对象的功能:
readObject()
:从流中读取一个对象(反序列化)。writeObject (Object obj)
:向流中写入一个对象(序列化)。
- 使用流传输对象的过程称为序列化、反序列化。
ObjectOutputStream
- 创建一个学生类,并实现
Serializable
标识接口:
Student.java
package com.clown.io;
import java.io.Serializable;
//学生类
public class Student implements Serializable { //实现 Serializable标识接口
//serialVersionUID: 序列化版本号ID。保证序列化对象的类和反序列化对象的类是同一个类
private static final long serialVersionUID = -8754718655236445126L;
//属性
private String name;
private int age;
//private transient int age; //若使用 transient(瞬间的)修饰属性,则此属性不能被序列化
//private static int age = 20; //静态属性也不能被序列化
//无参构造
public Student() {
}
//有参构造
public Student(String name, int age) {
this.name = name;
this.age = age;
}
//get() & set()
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//重写 toString() 美化打印
@Override
public String toString() {
return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
- 使用
ObjectOutputStream
序列化一个学生对象:
ObjectOutputStreamDemo01
package com.clown.io;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
/*
使用 ObjectOutputStream实现对象的序列化:
注意事项:
1. 序列化的对象的类型必须要实现 Serializable标识接口(此接口内没有方法或字段)
2. 序列化的对象所包含的属性的类型也必须要实现 Serializable标识接口
3. 添加序列化版本号ID(serialVersionUID),保证序列化对象的类和反序列化对象的类是同一个类
4. 若使用 transient(瞬间的)修饰某个属性,则此属性不能被序列化
5. 静态属性也不能被序列化
6. 序列化与反序列化多个对象时,可以借助集合来实现
*/
public class ObjectOutputStreamDemo01 {
public static void main(String[] args) throws Exception {
//1. 创建对象流
FileOutputStream fos = new FileOutputStream("d:\\JavaTest\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//创建学生对象
Student zhangsan = new Student("张三", 20);
//2. 序列化(写入操作)
oos.writeObject(zhangsan);
//3. 关闭
oos.close();
System.out.println("序列化完毕");
}
}
运行结果:
查看文件:
ObjectInputStream
- 使用
ObjectInputStream
反序列化一个学生对象:
ObjectInputStream.java
package com.clown.io;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/*
使用 ObjectInputStream实现对象的反序列化(读取并重构成对象)
*/
public class ObjectInputStreamDemo01 {
public static void main(String[] args) throws Exception {
//1. 创建对象流
FileInputStream fis = new FileInputStream("d:\\JavaTest\\stu.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
//2. 反序列化(读取操作)
Object obj = ois.readObject();
Student s = (Student) obj;
//3. 关闭
ois.close();
System.out.println("反序列化完毕");
//打印
System.out.println(s.toString());
}
}
运行结果:
补充:序列化/反序列化多个对象
- 序列化:
package com.clown.io;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/*
使用 ObjectOutputStream实现对象的序列化:
注意事项:
1. 序列化的对象的类型必须要实现 Serializable标识接口(此接口内没有方法或字段)
2. 序列化的对象所包含的属性的类型也必须要实现 Serializable标识接口
3. 添加序列化版本号ID(serialVersionUID),保证序列化对象的类和反序列化对象的类是同一个类
4. 若使用 transient(瞬间的)修饰某个属性,则此属性不能被序列化
5. 静态属性也不能被序列化
6. 序列化与反序列化多个对象时,可以借助集合来实现
*/
public class ObjectOutputStreamDemo01 {
public static void main(String[] args) throws Exception {
//1. 创建对象流
FileOutputStream fos = new FileOutputStream("d:\\JavaTest\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//创建学生对象
Student zhangsan = new Student("张三", 20);
Student lisi = new Student("李四", 18);
//创建集合
ArrayList<Student> list = new ArrayList<Student>();
//将元素添加到集合中
list.add(zhangsan);
list.add(lisi);
//2. 序列化(写入操作)
oos.writeObject(list);
//3. 关闭
oos.close();
System.out.println("序列化完毕");
}
}
运行结果:
查看文件:
- 反序列化:
package com.clown.io;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
/*
使用 ObjectInputStream实现对象的反序列化(读取并重构成对象)
*/
public class ObjectInputStreamDemo01 {
public static void main(String[] args) throws Exception {
//1. 创建对象流
FileInputStream fis = new FileInputStream("d:\\JavaTest\\stu.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
//2. 反序列化(读取操作)
ArrayList<Student> list = (ArrayList<Student>) ois.readObject();
//3. 关闭
ois.close();
System.out.println("反序列化完毕");
//打印
System.out.println(list.toString());
}
}
运行结果: