package com.a27序列化;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class a01序列化 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
对象序列化流();
对象反序列化流();
}
public static void 对象序列化流() throws IOException, ClassNotFoundException {
Student stu = new Student(1001,"方光曦","男","大三");
Student stu1 = new Student(1002,"罗明星","女","大三");
List<Student> a = new ArrayList<>();
a.add(stu);
a.add(stu1);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("stu.txt",true));
//将对象序列化到文件
oos.writeObject(stu);
oos.close();
}
public static void 对象反序列化流() {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("stu.txt"));
Object obj=null;
while ((obj=ois.readObject())!=null){
Student stu = (Student) obj;
System.out.println(stu.getId()+","+stu.getName()+","+stu.getGender()+","+stu.getGrade());
}} catch (EOFException e) {
}
catch (Exception e) {
e.printStackTrace();
}finally {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.a27序列化;
import java.io.Serializable;
public class Student implements Serializable {
private int id;
private String name;
private String gender;
private String grade;
public Student(int id, String name, String gender, String grade) {
this.id = id;
this.name = name;
this.gender = gender;
this.grade = grade;
}
public Student() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", grade='" + grade + '\'' +
'}';
}
}
https://blog.csdn.net/xcwll_sina/article/details/39370443
while ((obj=ois.readObject())!=null){
Student stu = (Student) obj;
System.out.println(stu.getId()+","+stu.getName()+","+stu.getGender()+","+stu.getGrade());
}
报错是因为这个while循环有问题,因为你只write了一个对象到文件,当你read第二次的时候就会抛异常。
你只write一个对象,读取的时候也不需要while循环,直接
obj=ois.readObject()
即可。
知道错误原因,你就可以根据需要修改代码了。
如有帮助,请采纳,十分感谢!
1.在一个文件都有一个文件的头部和文件体。由于对多次使用FileOutputStream(文件名,true)构建的ObjectOutputStream对象向同一个文件写数据,在每次些数据的时候他都会向这个文件末尾先写入header在写入你要写的对象数据导致的。
2.解决办法:如图
写类:
public class ObjectAppendOutputStream extends ObjectOutputStream {
public ObjectAppendOutputStream() throws IOException {
super();
}
public ObjectAppendOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
protected void writeStreamHeader() throws IOException {
return;
}
}
然后改你的写入操作为
File file = new File("stu.txt");
if (file.exists() == false) {
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file, true);
if (file.length() < 1) {
oos = new ObjectOutputStream(fos);
} else {
oos = new ObjectAppendOutputStream(fos);
}
不需要循环
题主这个问题,并不是写一个然后循环读的问题。就算写一个,用循环读一样可以读出来,不会报错。出现报错是因为第二次执行向文件追加内容,再读就出现了问题。如果想要不报错,这里改为false就好
1)运行结果:
2)主要修改:
3)主要原理:
操作系统层面有写延迟,读文件时还没来得急写确认,所以报错AC (acknowledge的意思),
头写尾巴读,就没问题
4)调测不易,望采纳
5)代码在这里:
package com.askdebug.csdn.service.impl;
import com.askdebug.csdn.modal.Student;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class a01序列化 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
对象序列化流();
对象反序列化流();
}
public static void 对象序列化流() throws IOException, ClassNotFoundException {
Student stu = new Student(1001,"方光曦","男","大三");
Student stu1 = new Student(1002,"罗明星","女","大三");
List<Student> a = new ArrayList<>();
a.add(stu);
a.add(stu1);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("stu.txt",false));
//将对象序列化到文件
oos.writeObject(stu);
oos.writeObject(stu1);
oos.close();
}
public static void 对象反序列化流() {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("stu.txt"));
Object obj=null;
while ((obj=ois.readObject())!=null){
Student stu = (Student) obj;
System.out.println(stu.getId()+","+stu.getName()+","+stu.getGender()+","+stu.getGrade());
}} catch (EOFException e) {
}
catch (Exception e) {
e.printStackTrace();
}finally {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.askdebug.csdn.modal;
import java.io.Serializable;
/**
* @author pcj
* @date 2022/4/8
* @note
*/
public class Student implements Serializable {
private int id;
private String name;
private String gender;
private String grade;
public Student(int id, String name, String gender, String grade) {
this.id = id;
this.name = name;
this.gender = gender;
this.grade = grade;
}
public Student() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Stu{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", grade='" + grade + '\'' +
'}';
}
}
报错原因:
因为你写文件是可以拼接的,而你的输出流是对象,对象在一次输出的时候回写一个输出流的头,里面包含类的信息,就你这个代码里面,输出文件会有输出的类是Student类型,当你关闭输出流,再次打开文件往里写的时候,这个输出流的头会再写一遍,这就导致读的时候,只读一次类型信息,然后认为之后的就都是该类型的信息,当再次读到这个类型信息的时候就会无法识别,例子如下:
输出的文件
第一次关闭输出流的时候文件变成
头信息:这是一个Student类的输出文件 数据:1001,方光曦,男,大三;1002,罗明星,女,大三;
这个时候你读去信息是没有问题的
当你再次运行相同文件的时候,输出文件就变成下面这样了
头信息:这是一个Student类的输出文件 数据:1001,方光曦,男,大三;1002,罗明星,女,大三;头信息:这是一个Student类的输出文件 数据:1001,方光曦,男,大三;1002,罗明星,女,大三;
这个时候你会看到,有连个头信息,你再去读取,当读到头信息的时候,你就无法解析了。
解决方法:
你需要自己在写一个类,该类主要的作用就是,当判断文件中已经有信息的时候,不再写入头信息。
代码如下:
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class a01序列化 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
对象序列化流();
对象反序列化流();
}
public static void 对象序列化流() throws IOException, ClassNotFoundException {
Student stu = new Student(1001,"方光曦","男","大三");
Student stu1 = new Student(1002,"罗明星","女","大三");
List<Student> a = new ArrayList<>();
a.add(stu);
a.add(stu1);
File file = new File("stu.txt");
ObjectOutputStream oos = null;
if(file.length()>1){
oos = new AppendObjectOutputStream(new FileOutputStream(file, true));
} else {
oos = new ObjectOutputStream(new FileOutputStream(file, true));
}
//将对象序列化到文件
for(Student student:a){
oos.writeObject(student);
}
oos.close();
}
public static void 对象反序列化流() {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("stu.txt"));
Object obj=null;
while ((obj=ois.readObject())!=null){
Student stu = (Student) obj;
System.out.println(stu.getId()+","+stu.getName()+","+stu.getGender()+","+stu.getGrade());
}} catch (EOFException e) {
}
catch (Exception e) {
e.printStackTrace();
}finally {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 可拼接的对象输出流
*/
class AppendObjectOutputStream extends ObjectOutputStream{
public AppendObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
protected void writeStreamHeader() throws IOException {
return;
}
}
Student类不变
应该是写序列化文件多次造成的, 建议楼主别整些中文,随便一个单词都好,中文可读性太差了
中文方法名?这是用的什么编程语言?
读取的时候也不需要while循环
代码改成如下试试:望采纳
public class a01序列化{
public static void main(String[] args) throws IOException, ClassNotFoundException {
对象序列化流();
对象反序列化流();
}
public static void 对象序列化流() throws IOException, ClassNotFoundException {
ObjectOutputStream out = null;
String path = "d://test.txt";
Student stu = new Student(1001,"方光曦","男","大三");
Student stu1 = new Student(1002,"罗明星","女","大三");
List<Student> a = new ArrayList<>();
a.add(stu);
a.add(stu1);
try { //判断文件大小并调用不同的方法
File file = new File(path);
FileOutputStream fos = new FileOutputStream(file, true);
if(file.length()<1){
out = new ObjectOutputStream(fos);
}else{
out = new MyObjectOutputStream(fos);
}
//判断文件大小并调用不同的方法
for (int i = 0; i < a.size(); i++) {
out.writeObject(a.get(i));
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void 对象反序列化流() {
String path = "d://test.txt";
ObjectInputStream in = null;
try {
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(path)));
while (true) {
Student s = (Student) in.readObject();
System.out.println(s.getId()+","+s.getName()+","+s.getGender()+","+s.getGrade());
}
} catch (EOFException e) {
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class MyObjectOutputStream extends ObjectOutputStream {
protected MyObjectOutputStream() throws IOException, SecurityException {
super();
}
@Override
protected void writeStreamHeader() throws IOException {
}
public MyObjectOutputStream(OutputStream o) throws IOException{
super(o);
}
}