通过ObjectOutputStream的writeObject方法进行Java ArrayList序列化将不起作用

时间:2018-10-02 07:23:50

标签: java file arraylist serialization io

我有一个“命令”类的方法,该方法应该将ArrayList保存到文件中,但是可以节省垃圾。 该方法采用一个ArrayList,其中包含实现Serializable的类(啤酒)的对象(在类名之后仅具有“ implements Serializable”关键字,没有方法实现)。看起来像这样:

public class Save implements Command {
    public void execute(ArrayList<Beer> beers, String cmd []) {
    if(cmd[0].equals("save")) {


        File file = new File(cmd[1]);
        try
        {
           FileOutputStream fileOut = new FileOutputStream(file);
           ObjectOutputStream out = new ObjectOutputStream(fileOut);
           out.writeObject(beers);
           out.close();
        }
        catch(IOException i)
        {
            i.printStackTrace();
        }

    }
}
}

对于具有以下属性的啤酒的列表:

[beername] [type] [strength]

heineken idk 5.3

pilsner idk 4.2

这是文件中的内容:

¬ssrjava.util.ArrayListxŇ™ÇaťI sizexp w srbeeregister.BeerřmRÁđ€óF strengthL namet Ljava / lang / String; L styleq〜xp @©™šheinekentidksq〜@†fft pilsnert idkx

我的加载方法也具有相同的样式,并且它不会将上面的垃圾读回到ArrayList。

public class Load implements Command {
@SuppressWarnings("unchecked")
public void execute(ArrayList<Beer> beers, String cmd[]) {
    if(cmd[0].equals("load")) {
        File file = new File(cmd[1]);
        try {
            FileInputStream fin= new FileInputStream (file);
            ObjectInputStream ois = new ObjectInputStream(fin);
            beers = (ArrayList<Beer>)ois.readObject();
            fin.close();
        }
        catch(IOException i) {
            i.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
}

我应该如何修改此代码,使其仅将属性保存到文本文件中,然后将其正确加载回去?我想坚持使用ObjectOutputStream的readObject和writeObject方法。 谢谢

2 个答案:

答案 0 :(得分:0)

与其将ArrayList对象作为参数传递给load方法,您应该在load方法内部创建新的arraylist并将序列化的文件读取到列表中,并在方法末尾将其返回。

 public ArrayList<Beer> execute( String cmd[]) {
    ...

    return ((ArrayList<Beer>) ois.readObject());
}

答案 1 :(得分:0)

我认为您的问题是Load.execute方法的设计,而不是读/写过程本身,因为后者 作品。但是在您当前的设计中,加载的数据会丢失。您必须按如下所示更改Load.execute方法。

要么更改方法的签名,要么在方法内部声明一个List-parameter,然后将其填充即可 并返回:

public class Load implements Command {
    @SuppressWarnings("unchecked")
    public List<Beer> execute(String cmd[]) {
        List<Beer> beers = null;
        if(cmd[0].equals("load")) {
            ...
        }
        return beers;
    }
}

或使用addAll方法而不是赋值填充传递的列表(因为后者不填充传递的列表):

public class Load implements Command {
    @SuppressWarnings("unchecked")
    public void execute(ArrayList<Beer> beers, String cmd[]) {
        ...
        beers.addAll((ArrayList<Beer>) ois.readObject());
        ...
    }
}