Как решить InvalidClassException при чтении массива объектов в ObjectInputStream?

Мне нужно сохранить и загрузить шахматную партию. В шахматах у меня:

public class Chess 
{
private Piece[][] pieceArray;
private Board board;
private int moves;
private boolean turn;
...
Set's and get's
}

Пришлось бы грузить ход, ходы и матрицу. Пока я только сохраняю и загружаю матрицу (Pieces[][])

Теперь у меня есть эти методы для сохранения и загрузки игры в другом классе. В этом классе у меня есть FTPClient, подключенный к серверу.

Сохранение игры:

public boolean saveGame(Chess chess) {
    boolean error = false;
    try {

        File file = new File("game.save");
        FileOutputStream fis = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(fis);
        oos.writeObject(chess.getArray());
        oos.close();

        // Save that file in the server
        FileInputStream fis = new FileInputStream(new File("game.save"));
        client.storeFile("game.save", fis);

        fis.close();
        file.delete();


    } catch (IOException e) {

        e.printStackTrace();
    }
    return error;

Сохранение игры не вызывает у меня проблем и проходит гладко.

И теперь это метод, который я использую для загрузки игры, который вызывает исключение invalidClassException.

try {
            FileInputStream fis = new FileInputStream(new File("game.save"));
            ObjectInputStream ois = new ObjectInputStream(fis);
            chess.setArray((Piece[][]) ois.readObject());
            chess.paintInBoard();
            ois.close();
        } catch (IOException | ClassNotFoundException e) {

            e.printStackTrace();
        }

Всякий раз, когда я пытаюсь прочитать матрицу, я получаю «java.io.InvalidClassException: [LPiece;; недопустимый дескриптор для поля»

Я реализовал интерфейс Serializable в Piece and Chess. Я попытался сохранить весь класс Chess, но при этом мне пришлось бы реализовать интерфейс Serializable и в других 8 классах, и я пытаюсь этого избежать. Должен ли я читать каждое произведение отдельно?

Большое тебе спасибо.


person Community    schedule 03.01.2016    source источник


Ответы (2)


Трудно определить, в чем может быть проблема, потому что интерфейс Piece и его реализующие классы не предоставляются, но вот мои мысли по этой проблеме:

  1. Лично я бы не стал сохранять массив или матрицу. Вместо этого я бы сохранил части в классе-контейнере, например: PieceCollection.
  2. Я не вижу какой-либо конкретной проблемы с предоставленным вами кодом (если только chess.getArray() не возвращает что-то еще, кроме pieceArray).
  3. Я считаю, что основная проблема здесь заключается в том, что ObjectInputStream не может различать различные реализации Piece. Я бы посоветовал вам добавить serialVersionUID в реализующие классы Piece. Для получения дополнительной информации см. следующую ссылку: https://docs.oracle.com/javase/7/docs/platform/serialization/spec/class.html
  4. В классах Piece отсутствует конструктор без аргументов. Для получения дополнительной информации см. следующую ссылку: https://docs.oracle.com/javase/8/docs/api/index.html?java/io/InvalidClassException.html

Удачи! Я надеюсь, что этот ответ поможет вам.

person Karl Dahlgren    schedule 03.01.2016

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

person Community    schedule 07.01.2016