2

我试图更好地理解对象序列化,所以我正在练习我从教科书中得到的一些代码。(我的教科书没有解释每次程序启动时如何读取和写入/附加对象到序列化文件,这是我需要做的。)我采用了他们的程序,它只是用对象覆盖文件中的现有数据从当前会话中,并向其中添加代码,以便它将附加对象并改为读取整个文件。我在这里发现了一些非常有用的东西:附加到 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();

    }
}
4

3 回答 3

1

我建议这样做

    ObjectOutputStream o1 = new ObjectOutputStream(new FileOutputStream("1"));
    ... write objects
    o1.close();
    ObjectOutputStream o2 = new AppendingObjectOutputStream(new FileOutputStream("1", true));
    ... append objects
    o2.close();

它绝对有效。

于 2013-01-31T06:05:56.637 回答
1
import EJP;
import Evgeniy_Dorofeev;

public class answer
{
    private String answera, answerb;
    public answer(String a, String b)
    {
        answera = a;
        answerb = b;
    }
    public void main(String[] args)
    {
        answer(EJP.response(), Evgeniy_Dorofeev.response());
        System.out.println(answera + '\n' + answerb);
    }
}
于 2013-02-01T09:06:34.610 回答
0

在追加的情况下,您需要为 new FileOutputStream() 的追加参数添加一个“真”。否则你不是。附加,就是这样。

于 2013-01-31T05:22:21.403 回答