【问题标题】:Java ArrayList serialization through ObjectOutputStream's writeObject method won't work通过 ObjectOutputStream 的 writeObject 方法进行的 Java ArrayList 序列化不起作用
【发布时间】:2018-10-02 07:23:49
【问题描述】:

我有一个“命令”类的方法,它应该将 ArrayList 保存到文件中,但它可以节省垃圾。 该方法采用一个 ArrayList,其中包含实现 Serializable 的类 (Beer) 的对象(在类名之后只有“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

这是文件中的内容:

¬í sr java.util.ArrayListxŇ™Çať I sizexp w sr beeregister.BeerřmRÁđ€ó F strengthL namet Ljava/lang/String;L styleq ~ xp@©™št heinekent idksq ~ @†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 方法。 谢谢

【问题讨论】:

  • 读取文件后你在 beers ArrayList 中得到了什么?该文件是二进制文件,因此不要期望能够通过纯文本读取它。
  • 同样在写入文件后执行 fileOut.close();
  • 发布您收到的错误消息。 “不将上面的垃圾读回 ArrayList”是一个无用的问题描述。 发生了什么? “它不起作用”提供零信息。

标签: java file arraylist serialization io


【解决方案1】:

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

要么更改方法的签名,要么在方法中声明一个列表参数,然后按照你已经填写的方式填写 执行并返回:

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());
        ...
    }
}

【讨论】:

    【解决方案2】:

    与其将 ArrayList 对象作为参数传递给 load 方法,不如在 load 方法中创建新的 arraylist 并将序列化文件读取到列表中并在方法结束时返回。

     public ArrayList<Beer> execute( String cmd[]) {
        ...
    
        return ((ArrayList<Beer>) ois.readObject());
    }
    

    【讨论】:

      猜你喜欢
      • 2015-01-09
      • 2014-04-16
      • 1970-01-01
      • 2018-09-23
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      相关资源
      最近更新 更多