细说缓冲流和包装流
一、缓冲流
1.缓冲流概念
1)访问硬盘时间资源开销大
2)缓冲流自带缓冲区域
3)缓冲区域减少硬盘访问次数,提高读取文件效率
2.缓冲流的分类
字节缓冲流和字符缓冲流。
a)字节缓冲流
i)字节缓冲输入/输出流:BufferedInputStream/BufferedOutputStream
ii)继承于FilterInputStream/FilterOutputStream类
iii)FilterInputStream/FilterOutputStream继承于InputStream/OutputStream抽象基类
iv)BufferedInputStream/BufferedOutputStream的作用就是为“输入/输出字节流提供缓冲功能”
v)BufferedInputStream/BufferedOutputStream没有声明自己任何新的方法,它只是覆盖了基类方法
vi)缓冲输入流每次读入和写出操作都是对缓冲区域执行的,而不是直接操作硬盘文件
vii)字节缓冲输入/输出流方法摘要:方法请参考FileInputStream/FileOutputStream方法使用格式
注意:缓冲流属于包装流,只能对已有的流进行封装,不能直接关联文件进行操作
例如:
public class Test {
public static void main(String[] args) throws Exception {
//创建文件对象
File file=new File("C:/Users/lenovo/Desktop/test.txt");
//创建文件输入流对象
FileInputStream fos=new FileInputStream(file);
//字节流转换为字符流
InputStreamReader isr=new InputStreamReader(fos);
//创建缓存流对象
BufferedReader bis=new BufferedReader(isr);
//建立一个容器
char[] bytes=new char[4];
int value=bis.read(bytes);
while(value!=-1){
String str=new String(bytes,0,value);
System.out.print(str);
value=bis.read(bytes);
}
bis.close();
}
}
b)字符缓冲流
i)字符缓冲输入/输出流:BufferedReader/BufferedWriter
ii)继承于Reader/Writer抽象基类
iii)BufferedReader/BufferedWriter的作用就是为“输入/输出字符流提供缓冲功能”
iv)BufferedReader/BufferedWriter没有声明自己任何新的方法,它只是覆盖了基类方法
v)字符缓冲输入/输出流方法摘要:方法请参考FileReader/FileWriter方法使用格式
新增方法:readLine/newLine 读取一行数据(以换行为结束标记)/写入一个行分隔符
二、数据输入/输出流
(一)数据输入输出流概念
1)文件流和缓冲流仅仅支持简单的字节写入写出,支持的读入写出方法局限性比较大
2)数据流允许应用程序以适当方式将数据以Java基本数据类型写入和读出文件
3)数据流提供了比文件流和缓冲流更加丰富的读入写出操作
4)由于数据流底层依然是字节操作,所以数据流为字节流类型的拓展包装流
(二)数据流继承体系(DataInputStream/DataOutputStream)见上图
例如:
public class Test2 {
public static void main(String[] args) throws Exception {
int value = 10000;
//先将要保存的东西写入文件
// FileOutputStream fos = new FileOutputStream("C:/Users/lenovo/Desktop/test.txt");
// //包装为数据流
// DataOutputStream dos = new DataOutputStream(fos);
// dos.writeInt(value);//4
// dos.writeChar('a');//1
// dos.writeBoolean(true);//2
// dos.writeByte(24);//1
// dos.writeDouble(4.123123123);//8
// dos.writeFloat(4.33f);//4
// dos.writeLong(1000000000000000000l);//8
// dos.writeShort(100);//2
// dos.writeUTF("aaaaaaaa");
// dos.flush();
// dos.close();
// 读取文件
FileInputStream fis = new FileInputStream("C:/Users/lenovo/Desktop/test.txt");
DataInputStream dis = new DataInputStream(fis);
System.out.println(dis.readInt());
System.out.println(dis.readChar());
System.out.println(dis.readBoolean());
System.out.println(dis.readByte());
System.out.println(dis.readDouble());
System.out.println(dis.readFloat());
System.out.println(dis.readLong());
System.out.println(dis.readShort());
System.out.println(dis.readUTF());
fis.close();
}
}
三、对象流
(一)对象流概念
1)所谓对象流就是将对象进行流化后通过流传输,我们可以直接将流化后的对象进行文件读写操作
2)对象流化就是将java对象转化为字节序列
3)需要进行对象流传输的对象所关联的类必须序列化
(二)序列化:
1)需要序列化的类必须实现Serializable接口
2)Serializable接口没有抽象方法,只是标注该对象可以被序列化
3)没有实现Serializable接口类的对象是不能通过对象流传输的
(三)对象流基本操作
1.对象输出流(ObjectOutputStream):writeObjct(Object obj)方法可以对参数指定的obj对象进行序列化成字节,并把得到的字节写到输出流关联的终端(可以是文件或者是网络的URI)
2.对象输入流(ObjectInputStream):readObject()方法从一个终端(可以是文件或者网络URI)读取一个字节序列,再对当前字节序列进行反序列化为一个对象,并将当前对象返回
例如:
public class Student implements Serializable{
private String name;
private int age;
private String address;
public Student(String name, int age, String address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public class Test1 {
public static void main(String[] args) throws Exception {
// ArrayList<Student> list = new ArrayList<Student>();
// for (int i = 0; i < 10; i++) {
// Student stu = new Student("张三"+i,26+i,"湖南衡阳"+i);
// list.add(stu);
// }
// FileOutputStream fos = new FileOutputStream("C:/Users/minGe_000/Desktop/test.txt");
// ObjectOutputStream oos = new ObjectOutputStream(fos);
// oos.writeObject(list);
// oos.flush();
// oos.close();
FileInputStream fis = new FileInputStream("C:/Users/minGe_000/Desktop/test.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<Student> list = (ArrayList<Student>)ois.readObject();
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i).getName());
}
}
}