我试图更好地理解对象序列化,所以我正在练习我从教科书中得到的一些代码。(我的教科书没有解释每次程序启动时如何读取和写入/附加对象到序列化文件,这是我需要做的。)我采用了他们的程序,它只是用对象覆盖文件中的现有数据从当前会话中,并向其中添加代码,以便它将附加对象并改为读取整个文件。我在这里发现了一些非常有用的东西:附加到 ObjectOutputStream但即使我创建了 ObjectOutputStream 的子类,重写 writeStreamHeader 方法,如果文件已经存在,则调用此子类,这就是他们所做的,它仍然会抛出 CorruptedStreamException。我的猜测是我需要将指针设置回文件的开头,但这似乎没有必要,因为只有一个 ObjectOutputStream。所以,我的问题是,我还需要做什么?
编辑:这是一些代码。
写数据.java
import java.io.*;
import java.util.Scanner;
public class WriteData
{
private int number;
private String name;
private float money;
private ObjectInputStream testopen;
private ObjectOutputStream output; //This is for the output. Make sure that
//this object gets an instance of FileOutputStream so that it can write objects
//to a FILE.
private AppendObjectOutputStream appendobjects;
static Scanner input = new Scanner(System.in);
static DataClass d;
public void openfile()
{
//Try opening a file (it must have the ".ser" extension).
try
{
//output = new ObjectOutputStream(new FileOutputStream("test.ser"));
testopen = new ObjectInputStream(new FileInputStream("test.ser"));
}
//If there is a failure, throw the necessary error.
catch (IOException exception)
{
try
{
output = new ObjectOutputStream(new FileOutputStream("test.ser"));
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} //end case createfile
if (testopen != null)
{
try
{
testopen.close();
appendobjects = new AppendObjectOutputStream(
new FileOutputStream("test.ser"));
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void writedata()
{
//write the data until the user enters a sentry value.
System.out.println("Enter CTRL + z to stop input.\n");
System.out.print ("Enter the data in the following format: " +
"account_number name balance\n->");
while (input.hasNext())
{
System.out.print ("Enter the data in the following format: " +
"account_number name balance\n->");
try
{
number = input.nextInt();
name = input.next();
money = input.nextFloat();
//Make object with that data
d = new DataClass(number, name, money);
//write it to the file
if (output != null)
{
output.writeObject(d);
}
else if (appendobjects != null)
{
appendobjects.writeObject(d);
}
}
catch (IOException e)
{
System.out.println("Error writing to file.");
return;
}
}
System.out.println("\n");
} //end writedata
public void closefile()
{
try
{
if (output != null)
{
output.close();
}
else if (appendobjects != null)
{
appendobjects.close();
}
}
catch (IOException e)
{
System.out.println("Error closing file. Take precautions");
System.exit(1);
}
}
}
数据类.java
import java.io.Serializable;
public class DataClass implements Serializable
{
private int someint;
private String somestring;
private float somefloat;
public DataClass(int number, String name, float amount)
{
setint(number);
setstring(name);
setfloat(amount);
}
public void setint(int i)
{
this.someint = i;
}
public int getint()
{
return someint;
}
public void setstring(String s)
{
this.somestring = s;
}
public String getstring()
{
return somestring;
}
public void setfloat(float d)
{
this.somefloat = d;
}
public float getfloat()
{
return somefloat;
}
}
AppendObjectOutputStream.java
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
public class AppendObjectOutputStream extends ObjectOutputStream
{
public AppendObjectOutputStream(FileOutputStream arg0) throws IOException
{
super(arg0);
// TODO Auto-generated constructor stub
}
//This is a function that is default in ObjectOutputStream. It just writes the
//header to the file, by default. Here, we are just going to reset the
//ObjectOutputStream
@Override
public void writeStreamHeader() throws IOException
{
reset();
}
}
读取数据.java
import java.io.*;
import java.util.Scanner;
public class ReadData
{
private FileInputStream f;
private ObjectInputStream input; //We should the constructor for this
//object an object of FileInputStream
private Scanner lines;
public void openfile()
{
try
{
f = new FileInputStream("test.ser");
input = new ObjectInputStream (f);
//input.reset();
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
public void readdata()
{
DataClass d;
System.out.printf("%-15s%-12s%10s\n", "Account Number", "First Name",
"Balance");
try
{
while (true)
{
d = (DataClass)input.readObject(); //define d
//read data in from d
System.out.printf("%-15d%-12s%10.2f\n", d.getint(), d.getstring(),
d.getfloat());
}
}
catch (EOFException eof)
{
return;
}
catch (ClassNotFoundException e)
{
System.err.println("Unable to create object");
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void closefile()
{
try
{
if (input != null)
{
input.close();
}
}
catch (IOException ex)
{
System.err.println("Error closing file.");
System.exit(1);
}
}
}
序列化测试.java
public class SerializationTest
{
public static void main(String[] args)
{
ReadData r = new ReadData();
WriteData w = new WriteData();
w.openfile();
w.writedata();
w.closefile();
r.openfile();
r.readdata();
r.closefile();
}
}