缓冲流
-
字节缓冲流:
BufferedInputStream
,BufferedOutputStream
-
字符缓冲流:
BufferedReader
,BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
字节缓冲流
构造方法
-
public BufferedInputStream(InputStream in)
:创建一个 新的缓冲输入流。 -
public BufferedOutputStream(OutputStream out)
: 创建一个新的缓冲输出流。
效率测试: 查询API,缓冲流读写方法与基本的流是一致的,我们通过复制大文件(约10MB),测试它的效率。
import java.io.*;
public class Demo3 {
public static void main(String[] args) throws IOException {
File srcFile = new File("d:\\ideawork\\aaa\\bbb\\1.flv");
File desFile = new File("d:\\ideawork\\aaa");
String srcFileName = srcFile.getName();
desFile = new File(desFile,srcFileName);
long start = System.currentTimeMillis();
file_Copy4(srcFile,desFile);
long end = System.currentTimeMillis();
System.out.println(end-start);
}
//463毫秒
public static void file_Copy(File srcFile,File desFile) throws IOException {
OutputStream out = new BufferedOutputStream(new FileOutputStream(desFile));
InputStream in = new BufferedInputStream(new FileInputStream(srcFile));
int data = 0;
while ((data = in.read())!=-1){
out.write(data);
}
out.close();
in.close();
}
public static void file_Copy3(File srcFile,File desFile) throws IOException {
OutputStream out = new FileOutputStream(desFile);
InputStream in = new FileInputStream(srcFile);
int data = 0;
while ((data = in.read())!=-1){
out.write(data);
}
out.close();
in.close();
}
//108毫秒
public static void file_Copy2(File srcFile,File desFile) throws IOException {
OutputStream out = new BufferedOutputStream(new FileOutputStream(desFile));
InputStream in = new BufferedInputStream(new FileInputStream(srcFile));
int len = 0;
byte[] bytes = new byte[1024];
while ((len = in.read(bytes))!=-1){
out.write(bytes,0,len);
}
out.close();
in.close();
}
//310毫秒
public static void file_Copy4(File srcFile,File desFile) throws IOException {
OutputStream out = new FileOutputStream(desFile);
InputStream in = new FileInputStream(srcFile);
int len = 0;
byte[] bytes = new byte[1024];
while ((len = in.read(bytes))!=-1){
out.write(bytes,0,len);
}
out.close();
in.close();
}
}
字符缓冲流
构造方法
-
public BufferedReader(Reader in)
:创建一个 新的缓冲输入流。 -
public BufferedWriter(Writer out)
: 创建一个新的缓冲输出流。
特有方法
-
BufferedReader:
public String readLine()
: 读一行文字。 -
BufferedWriter:
public void newLine()
: 写一行行分隔符,由系统属性定义符号。
序列化
ObjectOutputStream类
构造方法
-
public ObjectOutputStream(OutputStream out)
: 创建一个指定OutputStream的ObjectOutputStream。
序列化操作
-
一个对象要想序列化,必须满足两个条件:
-
该类必须实现
java.io.Serializable
接口,Serializable
是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException
。 -
该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用
transient
关键字修饰。
ObjectInputStream类
构造方法
-
public ObjectInputStream(InputStream in)
: 创建一个指定InputStream的ObjectInputStream。
反序列化操作1
如果能找到一个对象的class文件,我们可以进行反序列化操作,调用ObjectInputStream
读取对象的方法:
-
public final Object readObject ()
: 读取一个对象。
public class DeserializeDemo {
public static void main(String [] args) {
Employee e = null;
try {
// 创建反序列化流
FileInputStream fileIn = new FileInputStream("employee.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
// 读取一个对象
e = (Employee) in.readObject();
// 释放资源
in.close();
fileIn.close();
}catch(IOException i) {
// 捕获其他异常
i.printStackTrace();
return;
}catch(ClassNotFoundException c) {
// 捕获类找不到异常
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
// 无异常,直接打印输出
System.out.println("Name: " + e.name); // zhangsan
System.out.println("Address: " + e.address); // beiqinglu
System.out.println("age: " + e.age); // 0
}
}
反序列化操作2
当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个InvalidClassException
异常。发生这个异常的原因如下:
-
该类的序列版本号与从流中读取的类描述符的版本号不匹配
-
该类包含未知数据类型
-
该类没有可访问的无参数构造方法
Serializable
接口给需要序列化的类,提供了一个序列版本号。serialVersionUID
该版本号的目的在于验证序列化的对象和对应类是否版本匹配。
序列化练习
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//先序列化再反序列
// writeList(); //序列化
readList(); //反序列
}
public static void writeList() throws IOException {
List<Person> list = new ArrayList<>();
list.add(new Person("柳智敏",20));
list.add(new Person("蔡依林",20));
list.add(new Person("rina",22));
ObjectOutputStream out =new ObjectOutputStream(new FileOutputStream("day21\\5.txt"));
out.writeObject(list);
out.close();
}
public static void readList() throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("day21\\5.txt"));
Object object = in.readObject();
List<Person> list = (List<Person>)object;
for (Person person : list) {
System.out.println(person);
}
in.close();
}
}