簡體   English   中英

從文件讀取和寫入對象的ArrayList的問題

[英]Problems with read and write an ArrayList of Objects from a file

我在將對象的ArrayList保存到文件時遇到問題,他們將其讀取。 我正在StackOverflow中搜索,但找不到錯誤...

我有和Classnotfound問題或讀取空值...

有人幫我嗎? 看起來寫作對我來說很好。

那是代碼:

// calls using the CLASS

        // Lets save distribution IFF asked to
        if (shouldSavePoiDistribution){

            List<POInode> listOfPOIs = new ArrayList<POInode>();
            for(Node n : Runtime.nodes) {   
                if (n instanceof POInode){
                    listOfPOIs.add((POInode) n);

                }
            }

            GlobalWriteAndLoadPositions saver = new GlobalWriteAndLoadPositions();
            saver.write(Global.distributionFolder,listOfPOIs);

        }

        // lets load a distribution IFF asked to
        if (shouldLoadPoiDistribution){

            Global.lastPOIloaded = 0;
            GlobalWriteAndLoadPositions loader = new GlobalWriteAndLoadPositions();
            Global.listOfLoadedPOIs = loader.load(Global.distributionFile);

        }


/////  CLASS to read and write object in file.

// The file look be correct its is created and the size varies...
// reading returns the corret size of the arraylist, but only wrong values IFF I try/catch "ois.readObject();" for ClassNotFound, otherwise, it raises an exception

package sinalgo.runtime;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import projects.nodes.nodeImplementations.POInode;


public class GlobalWriteAndLoadPositions {


    public GlobalWriteAndLoadPositions(){   
    }
    public void write(String folder, List<POInode> POIlist)  throws IOException {   
        int nextFileItarator = (int) Files.list(Paths.get(folder)).count();
        nextFileItarator++;
        FileOutputStream fout= new FileOutputStream (folder + nextFileItarator + ".txt");
        System.out.print("\n[Global] Trying SAVE a distribution on " + folder + nextFileItarator + ".txt" + ": ");
        ObjectOutputStream oos = new ObjectOutputStream(fout);      
        oos.writeObject(POIlist);
        oos.close();
        fout.close();
        POIlist.forEach((a)->System.out.print("POI " + a.ID + " @ (" + a.getPosition().xCoord +" , " + a.getPosition().yCoord + ") | " ));
        System.out.println("\n");
    }
    public ArrayList<POInode> load(String file)  throws IOException{
        System.out.print("\n[Global] Trying LOAD a distribution: " + Global.distributionFile + " ||>  ");
        FileInputStream fin = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(fin);
        List<POInode> listOfLoadedPOIs = new ArrayList<POInode>();

        listOfLoadedPOIs = (ArrayList<POInode>) ois.readObject(); // THIS LOOK WRONG, I MEAN, Does not find the class POInode

        ois.close();    
        fin.close();
        listOfLoadedPOIs.forEach((a)->System.out.print("POI " + a.ID + " @ (" + a.getPosition().xCoord +" , " + a.getPosition().yCoord + ") | " ));
        System.out.println("\n");
        return (ArrayList<POInode>) listOfLoadedPOIs;   
    }
}

拜托,如何解決這個問題?

根據您的意見

listOfLoadedPOIs = (ArrayList<POInode>) ois.readObject();
   // readObject() throws ClassnotFound or empty values.

我們可以推斷發生了什么。

有兩種情況:

  1. 您先前對write方法的調用-使用了一個列表。 然后您的讀取代碼可以正常工作; 但是給您帶來的驚喜是您所寫的空名單。
  2. 您先前對write方法的調用-使用了NON空列表。 但是運行您的“讀取”代碼的JVM ...不知道該列表中存儲的對象的類。

因此,您的真正問題歸結為:“ java告訴我有關ClassNotFound的含義”; 答案可以在這里找到。

長話短說:測試“已讀”部分時,您的類路徑設置不完整; 因為java找不到您所存儲的對象種類的.class文件。

代碼的另一個問題:當您彼此“構建”這些流時,例如

WhateverStream inner = ...
SomeOtherStream outer = new SomeOtherStream(inner);

那么你只需要調用Close()/ ...上 ,但不是在內心。 實際上,甚至在您的代碼中,先執行inner.close(),然后執行outer.close()可能是另一個錯誤!

首先, 您如何使用這些方法

主要的麻煩在那里。

另外,還可以看到POInode類。

順便說一句 ,Smal的建議是對資源使用try而不是像您那樣關閉流:

// writing looks fine
public void write(String folder, ArrayList<POInode> POIlist) throws IOException {
    int nextFileItarator = (int) Files.list(Paths.get(folder)).count();
    nextFileItarator++;

    try (FileOutputStream fout = new FileOutputStream(folder + nextFileItarator + ".txt");
         ObjectOutputStream oos = new ObjectOutputStream(fout)) {

        oos.writeObject(POIlist);
    }
}

// I read the quantity OK, but empty or wrong values...
public ArrayList<POInode> load(String file) throws IOException {
    ArrayList<POInode> listOfLoadedPOIs = new ArrayList<POInode>();

    try (FileInputStream fin = new FileInputStream(file);
         ObjectInputStream ois = new ObjectInputStream(fin)) {

        // readObject() throws ClassnotFound or empty values.
        listOfLoadedPOIs = (ArrayList<POInode>) ois.readObject();
    }
    return (ArrayList<POInode>) listOfLoadedPOIs;
}

更好地遵循您的代碼樣式的方法將從final塊調用close()
但是,正如我之前說的,一個更好的主意是對try with resources使用try with resources 約書亞·布洛赫(Joshua Bloch)在他的《 有效的Java》 (第9項)中提出了建議:優先嘗試使用資源,而不是最終嘗試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM