ObjectInputStream反序列化
1. 序列化时,程序每执行一次,都会先写一个流头。 如果是追加模式,那么文件中可能会有多个流头 2. 反序列化时,也就是读取文件时,默认是只读取一次流头,剩下的内容全部认为是每个对象的信息。所以文件中如果有多个流头,可能会将除了第一个流头外,剩下的流头字节序列当成对象信息进行解析, 会报异常:java.io.StreamCorruptedException: invalid type code: AC
public class ObjectInputStreamDemo02 {
public static void main(String[] args) {
//创建一个反序列化的流对象
ObjectInputStream ois = null;
try{
ois = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream("./student.s"),4096));
Object obj = ois.readObject();
System.out.println(obj);
Object obj1 = ois.readObject();
System.out.println(obj1);
}catch (IOException | ClassNotFoundException e){
e.printStackTrace();
}finally {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
序列化
ObjectOutputStream:内存中的对象转成字节数组的过程,他的目的是存储或运输
反序列化时字节数组转化成内存的对象的过程
public class ObjectOutputStreamDemo01 {
public static void main(String[] args) {
//创建一个学生
Student s1 = new Student("小明",20,'男');
Student s2 = new Student("小红",21,'女');
//使用对象输出流,将学生写出到文件中
ObjectOutputStream oos null;
try{
ObjectOutputStream oos = null;
try{
oos = new ObjectOutputStream(
new BufferedOutputStream(
// 流的构造器的相对路径,相对的是Project文件夹。./表示项目文件夹
new FileOutputStream("./student.s",true),4096));
//写出对象
oos.writeObject(s1);
oos.writeObject(s2);
}catch (IOException e){
e.printStackTrace();
}finally {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class Student implements Comparable<Student>,Serializable{
public static final long serialVersionUID = 2100000000;
private String name;
private int age;
private char gender;
public Student(){}
public Student(String name, int age, char gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
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 char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && gender == student.gender && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, gender);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
'}';
}
@Override
public int compareTo(Student o) {
return this.age-o.age;
}
}
transient
关键字:修饰成员变量,,某一个属性的信息不需要保存或者传输,也就是不重要的意思。 那么就可以使用transient进行修饰。
public class ObjectOutputStreamDemo02 {
public static void main(String[] args) {
//创建一个Teacher对象
Teacher t = new Teacher("小明",20,"北京","askldjfalksjdf;laksjdf;kajdsf;klajsd;lfk");
//序列化Teacher
serialObject(t);
Teather t1 = deSerialObject();
System.out.println(t1);
}
public static void serialObject(Object obj){
ObjectOutputStream oos = null;
try{
oos = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream("object.txt")));
oos.writeObject(obj);
}catch (IOException e){
e.printStackTrace();
}finally {
try {
oos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
class Teacher implements Serializable,Comparable<Teacher> {
public static final int serialVersionUID = 1;
private String name;
private int age;
private String address;
private transient String remark;
public Teacher() {}
public Teacher(String name, int age, String address, String remark) {
this.name = name;
this.age = age;
this.address = address;
this.remark = remark;
}
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 String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Teacher teacher = (Teacher) o;
return age == teacher.age && Objects.equals(name, teacher.name) && Objects.equals(address, teacher.address) && Objects.equals(remark, teacher.remark);
}
@Override
public int hashCode() {
return Objects.hash(name, age, address, remark);
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", remark='" + remark + '\'' +
'}';
}
@Override
public int compareTo(Teacher o) {
return this.age - o.age;
}
}
字符输出流
1. 抽象父类Writer 2. 书写单位,以一个char为单位。 3. 底层依然是字节流。 4.基本的字符流我们称为转换流,因为涉及到字符与字节的转化所使用的编码集 5.默认字符集UTF-8。字母是一个字节,汉字三个字节 6.构造器:OutputStreamWriter(OutputStream os) OutputStreamWriter(OutputStream os,String charsetName)
public class _01WriterDemo {
public static void main(String[] args) {
OutputStreamWriter osw = null;
try{
osw = new OutputStreamWriter(
new FileOutputStream("./test07/char.txt"),"UNICODE"
);
osw.write('中');
char[] chs = {'喜','换','你'};
osw.write(chs);
osw.write(chs,chs.length-3,3);
osw.write("五星红旗迎风片样");
osw.flush();
}catch{IOException e}{
e.printStackTrace();
}finally{
try{
osw.close();
}catch(IOException e){
e.printStackTrace();
}
}
字符转换输入流InputStreamReader
构造器
InputStreamReader(InputStream os) InputStreamReader(InputStream os, String charsetname)
public class _02ReaderDemo {
public static void main(String[] args) {
InputStreamReader isr = null;
try {
isr = new InputStreamReader(
new FileInputStream("./test07/char.txt"),"GB2312");
//读取一个字符
for(int i=0;i<6;i++){
char ch = (char)isr.read();
System.out.println("ch: " + ch);
}
char[] chs = new char[10];
int length = -1;
while((length = isr.read(chs)) != -1){
System.out.println("chs: " + new String(chs,0,length));
System.out.println("len: " + length);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
isr.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}