一、缓冲流概述
- 缓冲流就是带有缓冲区的输入输出流,缓冲流可以显著的减少我们对IO访问的次数,保护我们的硬盘;
- 缓冲流本身就是处理流(处理流也叫包裹流),缓冲流必须得依附于节点流(节点流也叫原始流);
- 处理流是包裹在原始节点流上的流,相当于包括在管道上的管道。
二、缓冲流方法
- 缓冲流要”套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。
- J2SDK提供了四种缓存流,其常用的构造方法为:
BufferedReader(Reader in);
BufferedReader(Reader in,int sz); //sz 为自定义缓存区的大小
BufferedWriter(Writer out);
BufferedWriter(Writer out,int sz);
BufferedInputStream(InputStream in);
BufferedInputStream(InputStream in,int size);
BufferedOutputStream(OutputStream out);
BufferedOutputStream(OutputStream out,int size);
- 缓冲输入流支持其父类的mark和reset方法;
- BufferedReader提供了readLine方法用于读取一行字符串(以\r或\n分隔);
- Bufferedwriter提供了newLine用于写入一个行分隔符‘
- 对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush方法将会使内存中的数立刻写出。
- BufferedOutputStream 和 BufferedlnputStream
- BufferedOutputStream:带缓冲的输出流,允许一次向硬盘写入多个字节的数据;
- BufferedlnputStream:带缓冲的输入流,允许一次向程序中读入多个字节的数据;
- BufferedOutputStream 和 BufferedInputStream 都是包裹流,必须的依附于OutputStream 和InputStream;
- 例子: 利用BufferedOutputStream 和 BufferedlnputStream完成大容量文件的复制,这远比单纯利用 FilelnputStream 和 FileOutputStream要快得多。
package com.ittanya.demo1;
import java.io.*;
//用字节流拷贝文本文件
public class InputStreamOutPutStream {
public static void main(String[] args) throws Exception{
//带缓冲区的输入字节流,这里包含了多态的知识
BufferedInputStream bis=new BufferedInputStream(
new FileInputStream("D:\\ideaProjects\\basic code\\javaday\\" +
"src\\com\\ittanya\\demo1\\InputStreamOutPutStream.java"));
//写入,随便写到D盘下的一个根目录里
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("D:\\Tanya.haha2"));
//BufferedInputStream x=new BufferedInputStream("D:/Tanya.haha");
//FileOutputStream fo=new FileOutputStream("D:\\Tanya.haha1");
byte[] buf=new byte[1024];//字节流所以写byte,如果是字符流就写char
int len;
len=bis.read(buf);//len是返回的读取到的字节数,buf存放的是从文件中读取的数据
while(-1!=len){
bos.write(buf);
len=bis.read(buf);
}
bos.flush();//刷新
bis.close();
bos.close();
}
}
6. 对象的序列化
(1)所谓序列化是指:把一个obiect对象直接转化为字节流,然后把这个字节流直接写入本地硬盘或网络中。如果要想把某个对象序列化,则必须要实现 Serializable接口
(2)Serializable接口中并没有任何方法,这种类型的接口被称为标记接口(起标识作用),如果一个类实现了 Serializable 接口,潜在含义就是告诉编译器这个类是允许被序列化的,如果程序中存在序列该对象的代码,编译器就会自动进行相应的处理去完成该对象的序列化,如果该对象没有实现 Serializable 接口,程序中却存在该对象被序列化的代码,编译器编译时就会报错;
(3)在Java中 transient修饰的成员变量在对象序列化时不被序列化。
(4)
import java.io.*;
public class TestObjectIo {
public static void main(String[] args) {
ObjectOutputStream oos=null;
ObjectInputStream ois=null;
Student ss=new Student("zhangsan",1,99.9f);
Student ss1;
try{
FileOutputStream fos=new FileOutputStream("d://java1.txt");
oos=new ObjectOutputStream(fos);
oos.writeObject(ss);
System.out.println("ss.name="+ss.name);
System.out.println("ss.sid="+ss.sid);
System.out.println("ss.score="+ss.score);
ois=new ObjectInputStream(new FileInputStream("d://java1.txt"));
ss1=(Student) ois.readObject();//(Student)不能省
System.out.println("ss1.name="+ss1.name);
System.out.println("ss1.sid="+ss1.sid);
System.out.println("ss1.score="+ss1.score);
}catch(FileNotFoundException e){
System.out.println("文件没有找到!");
System.out.println(-1);
}catch(Exception e){
e.printStackTrace();
System.out.println(-1);
}finally{
try{
oos.close();
ois.close();
}catch(Exception e){
e.printStackTrace();
System.out.println(-1);
}
}
}
}
class Student implements Serializable{
public String name;
public int sid=0;
transient public float score=0;//表示score成员不能被序列化,这一行会读取失败
public Student(String name,int sid,float score){
this.name=name;
this.sid=sid;
this.score=score;
}
}
运行结果: