使用缓冲流完成文件的复制
JAVA IO将流分为两类:节点流和处理流(过滤流)
节点流也称为低级流,特点:是实际链接程序与另一端的流,负责实际读写字节数据的流,读写一定是建立在节点流基础上进行的
处理流也称为高级流,特点是不能独立存在,必须连接在其他流上,目的是当数据经过当前流时对其进行操作简化我们的读写
实际开发中我们经常串联一组高级流最终到某个低级流上,读写数据可以以流水线式的加工处理完成复杂的读写,这个过程称为流的连接
文件流就是典型的低级流,是实际连接程序与文件的流,负责读写文件数据
节点流也称为低级流,特点是实际连接程序与另一端的流,负责实际读写字节数据的流
缓冲流:java.io.BufferedInputStream和BufferedOutputStream
缓冲流是一对高级流
FileInputStream fis =new FileInputStream("ac.gif");
缓冲默认的构造器
BufferedInputStream(InputStream in)
内部开辟的字节数组长度为8kb
BufferedInputStream(InputStream in,in size)
自行指定内部缓冲区(byte数组长度)
BufferedInputStream bis =new BufferedInputStream(fis);
FileOutputStream fos =new FileOutputStream("ac_cp.gif");
BufferedOutputStream bos =new BufferedOutputStream(fos);
int d;
long start =System.currentTimeMillis();
缓冲字节输入流的read方法第一次调用是会一次性读一组数据进入到内部的缓冲区,然后返回其中第一个字节,第二次调用时会直接将数组中第二个字节返回,直到所有字节均返回后,下次调用read方法会再次块读数据进入数组
因此缓冲流本质就是将我们的读写操作统一转换为块读形式来保证读写效率
while ((d=fis.read())!=-1){
fos.write(d);
}
long end=System.currentTimeMillis();
System.out.println("耗时:"+(end-start)+"ms");
bis.close();//同时关掉低级流,关流的时候关掉最高级的就可以
bos.close();
缓冲输出流的缓冲区问题
FileOutputStream fos =new FileOutputStream("bos.txt");
BufferedOutputStream bos =new BufferedOutputStream(fos);
String line ="天青色等烟雨";
byte[] data =line.getBytes(StandardCharsets.UTF_8);
bos.write(data);
void flush() 将当前缓冲区中已经缓存的数据一次性写出
//bos.flush(); //flush:冲水
System.out.println("写出完毕");
bos.close();
对象流
java.io.ObjectInputStream和ObjectOutputStream
对象流的功能:进行对象序列化与反序列化
对象序列化由对象输出流完成:将一个java对象按照其结构转换为一组字节的过程
对象反序列化由对象输入流完成:将一组字节还原为一个java对象的过程
将一个person对象写入文件person.obj中
String name ="刘桑";
int age =55;
String gender ="男";
String[] otherInfo = {"a","b","c"};
Person p =new Person(name,age,gender,otherInfo);
文件输出流(低级流):将字节写入指定文件
FileOutputStream fos =new FileOutputStream("person.obj");
对象输出流(高级流):将一个java对象进行序列化
ObjectOutputStream oos =new ObjectOutputStream(fos);
序列化
序列化是抛出异常
java.io.NotSerializableException
说明序列化的类没有实现可序列化接口:java.io.Serializable
这里将对象写出涉及到两个操作
对象经过文件流时,会被文件输出流转换为一组字符,这个过程称为对象序列化
序列化的字节在经过文件流被写入文件中(硬盘中),这个过程称为数据持久化
所谓持久化就是可以长久保存了
oos.writeObject(p);
System.out.println("写出完毕");
oos.close();
将person.obj的对象反序列化
FileInputStream fis = new FileInputStream("person.obj");
ObjectInputStream ois =new ObjectInputStream(fis);
对象输入流提供了反序列化的方法:
Object readObject()
该方法内部会通过对象输入流链接的流先将字节读取过来,然后将这些字节还原
为java对象后返回,返回时统一以Object形式返回
类造型 class cast
Object obj = ois.readObject();
Person person = (Person)obj;
//Person person =(Person)ois.readObject(); 上述两句的简写
System.out.println(person);
ois.close();
使用当前类测试对象流的序列化与反序列化
JAVA BEAN定义规范
1.属性私有化
2.提供属性公开的GET/SET方法
3.定义无参构造器
4.实现序列化接口
凡是需要进行序列化的类都必须实现Serializable接口,并且该类中所有引用类型的属性也要实现序列接口
public class Person implements Serializable {
public static final long serialVersionUID = 42L;
private String name;
private int age;
private String gender;
private String[] otherInfo;
public Person(){}
/**
* alt+insert
* 1:Constructor 全选里边的属性生成全参构造器
* alt+insert
* 1:Constructor 全选里面的属性生成全参构造器
*2:Getter and Setter 全选里面的属性生成所有属性的get set方法
* @param name
* @param age
* @param gender
* @param otherInfo
*/
public Person(String name, int age, String gender, String[] otherInfo) {
this.name = name;
this.age = age;
this.gender = gender;
this.otherInfo = otherInfo;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getGender() {
return gender;
}
public String[] getOtherInfo() {
return otherInfo;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", otherInfo=" + Arrays.toString(otherInfo) +
'}';
}
}