Сериализация Java ArrayList с помощью метода writeObject ObjectOutputStream не будет работать

У меня есть метод "командного" класса, который должен сохранять ArrayList в файл, но сохраняет мусор. Метод принимает ArrayList, содержащий объекты класса (Beer), который реализует Serializable (имея только ключевые слова «реализует 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 forceL 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();
        }

    }
}
}

Как мне изменить этот код, чтобы он сохранял только атрибуты в текстовый файл и правильно загружал их обратно? Я хотел бы придерживаться методов readObject и writeObject ObjectOutputStream. Спасибо

что вы получаете в пиве ArrayList после прочтения файла? Файл является двоичным, поэтому не ожидайте, что его можно будет прочитать через обычный текст.

Itamar Kerbel 02.10.2018 09:53

также после записи файла выполните fileOut.close ();

Itamar Kerbel 02.10.2018 09:54

Опубликуйте полученные сообщения об ошибках. "не читает мусор выше обратно в ArrayList" - бесполезное описание проблемы. Какие бывает? «Это не работает» не дает никакой информации.

Andrew Henle 02.10.2018 11:16
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
81
2

Ответы 2

Вместо того, чтобы передавать объект ArrayList в качестве параметра для метода загрузки, вы должны создать новый массив массивов внутри метода загрузки, прочитать сериализованный файл в список и вернуть его в конце метода.

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

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

Я предполагаю, что ваша проблема - это скорее дизайн вашего метода Load.execute, чем сам процесс чтения / записи, поскольку последний работает. Но с вашим текущим дизайном загруженные данные теряются. Вам необходимо изменить метод Load.execute следующим образом.

Либо измените подпись вашего метода, объявите параметр List внутри вашего метода, заполните его, как вы уже сделать и вернуть:

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

Другие вопросы по теме