Как сохранить объект, у которого есть ArrayList других объектов, используя DataOutputStream? - PullRequest
2 голосов
/ 17 марта 2020

Как сохранить объект, у которого есть ArrayList других объектов, используя DataOutputStream, а затем загрузить их из файла? Я использую сериализацию, но объекты ArrayList не хотят загружаться.

Здесь я сохраняю:

 void saveChunk(Chunk chunk) {
    String currentChunkName = SAVES_FOLDER + "\\" + name + "\\" + "chunk" + chunk.x0 + "_" + chunk.y0 + END_CHUNK_NAME;
    File f = new File(currentChunkName);
    if(!f.exists()) {
        try {
            f.createNewFile();
        } catch(IOException e) {
            e.printStackTrace();
            System.err.println("Can't create data for chunk " + currentChunkName);
        }
    }
    try {
        File chunkData = new File(currentChunkName);
        DataOutputStream dout = new DataOutputStream(new FileOutputStream(chunkData));
        try {
            ObjectOutputStream out = new ObjectOutputStream(dout);
            out.writeObject(chunk);
            for(Tree tree : chunk.trees) {
                out.writeObject(tree);
            }
        } catch(IOException e) {
            e.printStackTrace();
            System.err.println("Can't create ObjectOutputStream " + currentChunkName);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        System.out.println("Can't save chunk " + chunk.x0 + "_" + chunk.y0);
    }
}

И здесь я загружаю:

    Chunk loadChunk(int x0, int y0) {
    String currentChunkName = SAVES_FOLDER + "\\" + name + "\\" + "chunk" + x0 + "_" + y0 + END_CHUNK_NAME;
    try {
        File chunkData = new File(currentChunkName);
        if(!chunkData.exists()) {
            generateChunk(x0, y0);
        }
        DataInputStream din = new DataInputStream(new FileInputStream(chunkData));
        try {
            ObjectInputStream oin = new ObjectInputStream(din);
            try {
                Chunk chunk = (Chunk) oin.readObject();
                return chunk;
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        System.err.println("Can't find chunk " + x0 + "_" + y0);
    }
    return null;
}

Там Вы можете увидеть класс Chunk с List (ArrayList) деревьев:

public class Chunk implements Serializable {

public static final byte CHUNK_SIZE = 12;
private int[] floors = new int[CHUNK_SIZE * CHUNK_SIZE];
public List<Tree> trees = new ArrayList<>();

int x0, y0, x1, y1;

public Chunk(int x0, int y0) {
    this.x0 = x0;
    this.y0 = y0;
    x1 = x0 + CHUNK_SIZE;
    y1 = y0 + CHUNK_SIZE;
}

public void addNewTree(int x, int y) {
    Tree tree = new Tree(x, y);
    addTree(tree);
}

public void addTree(Tree tree) {
    trees.add(tree);
}........ect

Классы "Chunk" и "Tree" оба реализуют интерфейс Serializable. Но когда я пытаюсь запустить, это не работает: у меня просто серый экран. Но если я удаляю Serializable реализацию в классе "Tree", то работают только куски без деревьев, но другая не может загрузиться, и у меня есть черные области, и это исключения:

java.io.InvalidClassException: org.ixnomad.game.level.nature.trees.Tree; class invalid for deserialization
at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:150)
at java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:790)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1782)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at java.util.ArrayList.readObject(ArrayList.java:791)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1909)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1808)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2018)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1942)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1808)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at org.ixnomad.game.level.Level.loadChunk(Level.java:44)
at org.ixnomad.game.level.InfiniteLevelRenderer.checkVisibleChunks(InfiniteLevelRenderer.java:70)
at org.ixnomad.game.level.InfiniteLevelRenderer.renderLevel(InfiniteLevelRenderer.java:55)
at org.ixnomad.MainComponent$SoftwareComponent.render(MainComponent.java:156)
at org.ixnomad.MainComponent$RunComponent.run(MainComponent.java:140)
at java.lang.Thread.run(Thread.java:745)
...