IO流
一、流的分类
二、字节流
FileOutputStream
FileOutputStream是文件的字节输出流,我们使用该流可以以字节为单位将数据写入文件。
构造方法:
- FileOutputStream(File file):
创建一个向指定File对象表示的文件中写出数据的文件输出流。 - FileOutputStream(String filename):
创建一个向具有指定名称的文件中写出数据的文件输出流。
注意:
若指定文件已经包含内容,那么当时使用FOS对其写入数据时,会将该文件中原有数据全部清除。 若想在文件的原有数据 之后追加新数据则需要以下构造方法创建FOS。
- FileOutputScream(File file , boolean append);
创建一个向指定File对象表示的文件中写出数据的文件输出流。 - FileOutputScream(String filename , boolean append);
创建一个向具有指定名称的文件中写出数据的文件输出流。
常用的方法:
FileInputStream
FileInputStream是文件的字节输入流,我们使用该流可以以字节为单位从文件中读取数据。
构造方法:
- FileInputStream(File file);
创建一个从指定File对象表示的文件中读取数据文件输入流。 - FileInputStream(String name);
创建用于读取给定的文件系统中的路径名name所指定的文件的文件输入流。
常用的方法:
BufferedOutputStream
BufferedOutputStream缓冲输出流内部维护着一个缓冲区,每当我们向流写数据时都会先将数据存入缓冲区,当缓冲区已满时,缓冲流会将数据一次性写出。
构造方法:
常用方法:
BufferedInputStream
BufferedInputStream是缓冲字节的输入流。其内部维护了一个缓冲区 (字节数组,其中该数组长度DEFAULT_BUFFER_SIZE = 8192) ,使用该流在读取一个字节时 该流会尽可能多的一次性读取若干字节并存入缓冲区中,然后逐一将字节返回,直到缓冲区当中的数据被全部读取完毕,会再次读取若干字节从而反复,这样就减少了读取的次数,从而提高读取效率。
构造方法:
常用方法:
ObjectOutputStream
ObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。
注意:
只有支持java.io.Serializable接口的对象才能写入流中。注意实现该接口不需要重写任何方法,因为该接口中任何方法都没有,像这样的接口叫签名接口。
构造方法:
常用方法:
ObjectInputStream
ObjectInputStream是用来对对象进行反序列化的输入流。
使用ObjectInputStream反序列化前先使用ObjectOutputStream编写的原始数据和对象。ObjectOutputStream和ObjectInputStream可以分别与FileOutputStream和FileInputStream一起使用对对象提供持久性存储的应用程序。
构造方法:
常用方法:
eg:
/*
* 实体类
*/
public class Person implements Serializable{
/*
* 当一个类实现了Serializable接口后,应当定义一个常量:serialVersionUID
* 这个常量是序列化版本号。若不指定,编译器会在编译时按照当前类的结构生成一个版本号。但是若类的结构
* 发生改变,版本号会跟着改变。
* 序列化版本号直接影响对象输入流进行反序列化时是否能够成功。
* 当反序列化的对象与当前版本号一致,那么反序列化成功,否则反序列化时抛出异常。
* 若当前类结构发生了改变,只要版本号没有改变,那么反序列化时会将仍然有的属性进行还原。
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
/*
* 当一个属性使用transient修饰后,那么在进行序列化时,该属性的值会被忽略。
* 忽略不必要的属性可以达到对对象序列化的“瘦身”操作。
*/
private transient String otherInfo;
public Person(String name, int age, String otherInfo) {
super();
this.name = name;
this.age = age;
this.otherInfo = otherInfo;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", otherInfo=" + otherInfo + "]";
}
/*实现Person的序列化*/
@Test
public void testOOS() throws Exception{
FileOutputStream fos = new FileOutputStream("./src/com/tarena/yadx/io/person.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Person p = new Person("刘雯",18, "是一位国际模特");
/*
* 下面代码实际上做了两件事:
* 1.p对象先流经对象输出流,而对象输出流将该对象转换为了一组字节,这个过程称为对象序列化。
* 2.转换的这组字节再流经文件输出流,然后写入了文件保存(写入磁盘),将数据写入磁盘做长久
* 保存的过程称为数据持久化。
*/
oos.writeObject(p);
System.out.println("序列化完毕");
oos.close();
}
/*
* 实现person.obj的反序列化
*/
@Test
public void testOIS() throws Exception {
FileInputStream fis = new FileInputStream("./src/com/tarena/yadx/io/person.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
Person p = (Person)ois.readObject();//此处Object——>Person需要强转
System.out.println("反序列化完毕");
System.out.println(p);
ois.close();
}
三、字符流
InputStreamReader(转换流)
InputStreamReader字符输入流使用该流可以设置字符集,并按照指定的字符集从流中按照该编码将字节数据转化为字符数据并读取。
构造方法:
常用方法:
OutputStreamReader(转换流)
OutputStreamWriter字符输出流 使用该流可以设置字符集,并按照指定的字符集将字符转化为字节后通过流写出。
构造方法:
常用方法:
注意:
字符流读写单位是以字符为单位,所以字符流读写数据有一定的局限性,只能用于读写文本数据。 非文本数据不能使用字符流读取。
为什么要叫它转换流呢?
原因是:几乎所有的字符流都只能连接在其他字符流上,而基本上低级流都是字节流,由于InputStreamReader和OutputStreamWriter可以连接字节流,而本身其自身又是字符流,所以起到将字符流与字节流“对接”的作用。
BufferedReader
BufferedReader是缓冲字符输入流,其内部提供了缓冲区,可以提高读取效率。
构造方法:
( defaultCharBufferSize = 8192)
常用方法:
该方法会连续读取若干字符,当读取到换行符时,将之前读取的字符以字符串形式返回,若返回值为null时,表示流的末尾。
PrintWriter
具有自动行刷新的缓冲字符输出流,内部总是会连接BufferedWriter作为缓冲操作。
构造方法:
常用方法: