IO流(二)转换流、序列化、commons-IO框架
转换流
介于字符流和字节流之间的流
字节流与字节流相互转换
OutputStreamWriter
输出流,按照指定的字符集编码,把字符流转化成字节数据
编码:把字符数据转换成字节数据;
解码:把字节数据转换成字符数据 二进制数据—>字符数据
- 构造方法:
- OutputStreamWriter(OutputStream out) 创建使用默认字符(计算机系统的编码)编码的 OutputStreamWriter。
- OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter
- 方法
- void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,到文件中
- void write(int c) 写入单个字符,到文件中
- void write(String str, int off, int len) 写入字符串的某一部分,到文件中
InputStreamReader
输入流,将字节数据转换成字符数据
- 构造方法
方法
public class Demo { public static void main(String[] args) throws Exception { method("UTF-8"); } public static void method(String encoding) throws UnsupportedEncodingException, FileNotFoundException, IOException { InputStreamReader isr=new InputStreamReader(new FileInputStream("a.txt"),encoding); char [] cArray=new char[1024]; int len = isr.read(cArray); System.out.println(new String(cArray, 0,len)); isr.close(); } private static void method02() throws UnsupportedEncodingException, FileNotFoundException, IOException { OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8"); osw.write("中国"); System.out.println("写入成功"); osw.close(); } private static void method01() throws FileNotFoundException, IOException { OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("a.txt")); osw.write("你好"); System.out.println("写入成功"); osw.close(); }
}
序列化和反序列化
序列化(ObjectOutputStream):把java对象对应的二进制数据存储到文件中
反序列化(ObjectInputStream):把文件找中的对象二进制数据转成对象
反序列化出现类型无效异常怎么解决
Exception in thread “main” **java.io.InvalidClassException.**com.day12.text.Student; local class incompatible: stream classdesc serialVersionUID = 5347324120869492511, local class serialVersionUID = 6670513660087444604
原因:当初序列化时,使用类与现在反序列化的使用到的类不是同一个版本
解决方法:保证序列化用到的类与现在反序列化用到的这个类是同一个版本
利用版本号进行标记
private static final long serialVersionUID = 6670513660087444604L;
相同版本号的才可以进行反序列化
瞬态关键字transient
被标记的属性会被隐藏,不会被保存到文件中
怎么写入和读取多个对象
写入对象需要注意的是:每次更改了对象的属性或者方法时,都要重新写入到文件,不然会报出版本不匹配的异常。
读取对象:在读取对象时,不能像读取文件那样全部能读出来。读取只能读取对象文件首个元素。为了能读取多个元素可以使用数组或者集合来存放对象,将数组或者对象写入到文件中。然后在读取出来。
向文件中写入对象代码
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
public class DemoObjectOutputStream {
public static void main(String[] args) throws Exception {
//创建对象输出流
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("student1.txt"));
//创建集合存放学生对象
ArrayList<Student>list=new ArrayList<Student>();
//创建对象数组 将对象添加到集合
// Student[] stu=new Student[3];
// stu[0]=new Student("小白",87);
// stu[1]=new Student("呵呵",67);
// stu[2]=new Student("好好",77);
Student stu=new Student("好好",77);
Student stu1=new Student("好好1",77);
list.add(stu);
list.add(stu1);
//遍历集合将集合的内容添加到文件中
/* for(int i=0;i<list.size();i++){
Student student = list.get(i);
oos.writeObject(student);
}*/
//oos.writeObject(stu);
oos.writeObject(list);
System.out.println("写入成功");
oos.close();
}
}
读取对象到控制台(内存)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
public class DemoObjectInputStream {
public static void main(String[] args) throws Exception {
//创建对象输出流
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("student1.txt"));
//Student []stu=(Student[])ois.readObject();
ArrayList<Student> list = (ArrayList<Student>) ois.readObject();
System.out.println(list.get(0).getName());
ois.close();
}
}
学生对象代码
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private int grade;
public Student(String name, int grade) {
super();
this.name = name;
this.grade = grade;
}
@Override
public String toString() {
return "Student [name=" + name + ", grade=" + grade + "]";
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
}
commons-IO 框架
第三方框架这里有操作文件的工具类。