【问题标题】:Appending Java serialized objects附加 Java 序列化对象
【发布时间】:2018-02-07 06:40:37
【问题描述】:

我在 Java 文件 IO 操作方面需要一点帮助。我正在尝试将序列化对象附加到我的文件中,但只有最后一个对象被附加到文件中。 我尝试了很多建议,但还没有成功。 我如何才能做到这一点,请帮忙?

这是我的代码:

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Scanner;




public class Working {

     String FILENAME = "E:\\assignment\\userpass\\userpass.txt";

    Scanner sc = new Scanner(System.in);
    String sUser = null, sPass = null, sRole = null;

    Signup signup = new Signup();

    public void createUser(){

        System.out.println(" Enter username: ");
        sUser = sc.next();

        System.out.println(" Enter password: ");
        sPass = sc.next();

        System.out.println(" Enter Role: ");
        sRole = sc.next();


        Working obj = new Working();

        signup.setUsername(sUser);
        signup.setPassword(sPass);
        signup.setRole(sRole);

        obj.serializeUser(signup);


    }





public void serializeUser(Signup signup){

        FileOutputStream fout = null;
        ObjectOutputStream oout= null;

        File file = new File(FILENAME);

        try{

        //  fout = new FileOutputStream(file);
        //  fout = new FileOutputStream(file.getAbsoluteFile(), true);
            fout = new FileOutputStream(file, true);
        //  fout = new FileOutputStream(FILENAME);
            oout = new ObjectOutputStream(fout);
            oout.writeObject(signup);

            System.out.println("User has been serialized");

        } catch(Exception e){
            e.printStackTrace();

        } finally {

            if(fout != null){
                try{

                    fout.close();
                } catch(IOException e){
                    e.printStackTrace();
                }
            } 

            if(oout != null){
                try{

                    oout.close();
                } catch(IOException e){
                    e.printStackTrace();
                }
            } 

        }

    }


// for test purpose
public void showUsers(){
    Working obj = new Working();
    Signup add = obj.deserializeUser(FILENAME);

    System.out.println(add);
}

// to show data
//test purpose

public Signup deserializeUser(String filename){

    Signup userDetails = null;
    File file = new File(FILENAME);

    FileInputStream fin = null;
    ObjectInputStream oin = null;

    try{

        fin = new FileInputStream(file);
        oin = new ObjectInputStream(fin);

        userDetails = (Signup) oin.readObject();

    } catch(Exception ex){
        ex.printStackTrace();
    } finally{
        if (fin != null) {
            try {
                fin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (oin != null) {
            try {
                oin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return userDetails;

}

}

我已经在这里检查过: 1.http://www.enseignement.polytechnique.fr/informatique/Java/1.8/java/io/FileOutputStream.html#FileOutputStream-java.lang.String-boolean- 2.Appending to an ObjectOutputStream

【问题讨论】:

  • 快速浏览一下 ObjectOutputStream 文档并不会让我相信 writeObject 会附加新对象的重载。我认为这是有充分理由的。您可能要考虑不直接序列化对象,而是将其序列化为字符串,然后使用带有附加选项的输出流将其写入文件。反序列化将涉及将文件中的每一行解组为新的 Signup 对象。或者,您可以序列化对象的集合,并从中解组相同的集合类型。
  • @MarkW String 不是二进制数据的容器。
  • @EJP 我建议他将其序列化为字符串。他没有理由不能将他的对象编组为字符串。字符串可以是任何内容,从 XML 到字段的逗号分隔键值对。真的没关系。序列化就是序列化,与存储格式无关。
  • @MarkW 他正在使用 Java 对象序列化。它产生二进制格式。您不能将其序列化为String。如果您建议他使用不同的序列化程序,您需要这样说。
  • @EJP,我第一次看错了....不过。我说的是序列化,而不是使用对象序列化器进行二进制序列化。序列化并不是专门使用这种特定的序列化方法。我的评论对我来说似乎非常清楚。

标签: java serialization java-io


【解决方案1】:

你需要每次循环创建一个新的Signup对象,或者每次调用ObjectOutputStream.reset(),或者使用ObjectOutputStream.writeUnshared()

但是还有其他问题。

  • 您应该在文件输出流之前关闭对象输出流,或者代替。
  • 您不能追加到对象输出流,至少不能像这样简单。请参阅我关于“StreamCorruptedException - 无效类型代码 AC”的回答,了解为什么不这样做。您需要在第二个链接中使用该技术。

【讨论】:

    猜你喜欢
    • 2018-02-26
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多