1

アップデート

多大な支援をいただきありがとうございます。ここで、例外に関する考えられる理由を1つ追加する必要があります。

ドメイン クラス (以下の大学のクラスなど) にreadObject()とを追加し、さらに main() メソッドでメソッドを呼び出す必要がある場合は、次のことを確認してください。writeObject()ObjectOutputStream.writeObject()

ObjectOutputStream.close()---メソッドをドメイン クラスに配置しないでください。オブジェクトが閉じられているため、そのオブジェクトを操作することは違法であるため、例外が発生します (プログラムがファイルを読み取ったり、既に閉じられているファイルを閉じたりするにはどうすればよいでしょうか?)。

マイナーな問題であることはわかっていますが、例外はそれについて何も伝えないため、デバッグするのは非常に微妙です。だから、これは記録のために少し頭を上げています。


単純なスニペットを実装して、一時オブジェクトのプリミティブ フィールドをシリアル化し、ObjectInputStream によってそれらのプリミティブ フィールドを逆シリアル化し、最終的にそれらを使用して新しいオブジェクトを作成します。シナリオは次のようになります。

public class College implements Serializable{
    private static final long serialVersionUID = 1L;

    private String name;
    private transient City city; //transient
    private String zipCode;

    // constructors & getter/setters

private void writeObject(ObjectOutputStream os){
    try {
        os.defaultWriteObject();
        os.writeInt(city.getCode());
        os.writeInt(city.getPopulation());
        os.writeObject(city.getName());
        os.flush();
        os.close(); // update: not good practice, may throw exception.
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private void readObject(ObjectInputStream os){
    try {
        os.defaultReadObject();
        int code = os.readInt();
        int population = os.readInt();
        String name = (String)os.readObject();
        City theCity = new City(code, name, population);
        System.out.println(theCity.toString());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
}
}

シティクラスはこちら

public class City {
    // the primitive & String fields
    private int code;
    private String name;
    private int population;

    // getter/setters

}

そして、ここにオブジェクトを読み書きするための素敵なコードがありcollegeます(少し分厚いです、ごめんなさい)

public class GeneralTest {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    City city = new City(375, "New York", 380897);
    College college = new College("NYU", city, "10289");
    College readCollege = null;
    City readCity = null;
    
    System.out.println("Before serialization -- City: ["+city.toString()+"], College: ["+college.toString()+"]");
    
    try {
        FileOutputStream fs = new FileOutputStream("college.foo");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        os.writeObject(college);
        os.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    try {
        FileInputStream fis = new FileInputStream("college.foo");
        ObjectInputStream ois = new ObjectInputStream(fis);
        readCollege = (College)ois.readObject();

        //get values to compose a city object
        int id = ois.readInt();
        int population = ois.readInt();
        String name = ois.readUTF();
        readCity = new City(id, name, population);
        
        ois.close();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    System.out.println("After serialization -- City: ["+readCity.toString()+"], College: ["+readCollege.toString()+"]");
}

}

そして、私はこの例外を受け取り、readCollegeandreadCityは明らかにnullです:(

java.io.IOException: Write error
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:282)
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1847)
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1756)
    at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1257)
    at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1211)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1395)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1547)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:333)
    at serialized.GeneralTest.main(GeneralTest.java:27)
java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.readByte(ObjectInputStream.java:2721)
    at java.io.ObjectInputStream$BlockDataInputStream.readUTFChar(ObjectInputStream.java:3113)
    at java.io.ObjectInputStream$BlockDataInputStream.readUTFBody(ObjectInputStream.java:3010)
    at java.io.ObjectInputStream$BlockDataInputStream.readUTF(ObjectInputStream.java:2819)
    at java.io.ObjectInputStream.readUTF(ObjectInputStream.java:1050)
    at serialized.College.readObject(College.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at serialized.GeneralTest.main(GeneralTest.java:40)
java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2553)
    at java.io.ObjectInputStream.skipCustomData(ObjectInputStream.java:1899)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1873)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at serialized.GeneralTest.main(GeneralTest.java:40)
Exception in thread "main" java.lang.NullPointerException
    at serialized.GeneralTest.main(GeneralTest.java:52)

何か案は?前もって感謝します。

4

3 に答える 3

1

この行を実行すると:

readCollege = (College)ois.readObject();

その後、ストリームには何もありません。

したがって、同じストリームを読み込もうとすると、論理的に : (さらに、 byjava.io.EOFExceptionの置換に注意してください)readUTF()readObject()

//get values to compose a city object
        int id = ois.readInt();   // there's nothing more !! throws exception!
        int zip = ois.readInt();
        String name = (String)ois.readObject();

実際、ストリームへの書き込み中にカスタム値を追加していません。

したがって、解決策の一例として、に必要な要素を追加するための専用の 3 行を追加しますCity

try {
        FileOutputStream fs = new FileOutputStream("college.foo");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        os.writeObject(college);
        os.writeInt(1); //adding the id !
        os.writeInt(75019); //adding the zip !
        os.writeObject("name"); //adding the name !
        os.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

もちろん、読み取りフィールドの順序は、書き込み中のものと同じでなければなりません。

コメント後に更新:

実際、メソッドを介してクラスCity内のカスタム値を既に読み取っているため、これらの行は役に立ちません。CollegereadObject()

int id = ois.readInt();
int population = ois.readInt();
String name = (String)ois.readObject();   // remove them all

どうして ???前に説明したように、彼らは単にjava.io.EOFExceptionそれ以上読むべきものがないからです。

ここで動作するグローバル コード:

class College implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private transient City city; //transient
    private String zipCode;

    College(String name, City city, String zipCode) {
        this.name = name;
        this.city = city;
        this.zipCode = zipCode;
    }

    private void readObject(ObjectInputStream os) {
        try {
            os.defaultReadObject();
            int code = os.readInt();
            int population = os.readInt();
            String name = (String) os.readObject();
            this.city = new City(code, name, population);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void writeObject(ObjectOutputStream os) {
        try {
            os.defaultWriteObject();
            os.writeInt(1);
            os.writeInt(200);
            os.writeObject("thename");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public City getCity() {
        return city;
    }

    public void setCity(City city) {
        this.city = city;
    }

    public String getZipCode() {
        return zipCode;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }
}

class City {
    // the primitive & String fields
    private int code;
    private String name;
    private int population;

    City(int code, String name, int population) {
        this.code = code;
        this.name = name;
        this.population = population;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPopulation() {
        return population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

    // getter/setters
}

public class Launcher {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        City city = new City(375, "New York", 380897);
        College college = new College("NYU", city, "10289");
        College readCollege = null;
        City readCity = null;

        System.out.println("Before serialization -- City: [" + city.toString() + "], College: [" + college.toString() + "]");

        try {
            FileOutputStream fs = new FileOutputStream("college.foo");
            ObjectOutputStream os = new ObjectOutputStream(fs);
            os.writeObject(college);
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            FileInputStream fis = new FileInputStream("college.foo");
            ObjectInputStream ois = new ObjectInputStream(fis);
            readCollege = (College) ois.readObject();
            readCity = readCollege.getCity();

            ois.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("After serialization -- City: [" + readCity.toString() + "], College: [" + readCollege.toString() + "]");
    }

}
于 2012-11-01T15:24:01.900 に答える
1

出力するコードのセクションは次のとおりです

    FileOutputStream fs = new FileOutputStream("college.foo");
    ObjectOutputStream os = new ObjectOutputStream(fs);
    os.writeObject(college);
    os.close();

ストリームを作成し、collegeオブジェクトを書き込み、それを閉じます。

これがあなたが読んでいる部分です:

    FileInputStream fis = new FileInputStream("college.foo");
    ObjectInputStream ois = new ObjectInputStream(fis);
    readCollege = (College)ois.readObject();

この時点で、あなたは自分が書いたものをすべて読んだことになります。あなたは以前に大学を書いていましたが、今はそれを読んでいます。

次に、次のようにします。

    //get values to compose a city object
    int id = ois.readInt();
    int population = ois.readInt();
    String name = ois.readUTF();
    readCity = new City(id, name, population);

ここで何かを読んでいるとどうして期待できますか?あなたは書いただけcollegeです。次に、(参照を読みcollege戻しreadCollegeます。次に、さらに 2 つの int と文字列を読み取ろうとしていますか? そのデータはどこから来るのでしょうか? 読み取るものが残っていません。

于 2012-11-01T15:14:06.577 に答える
1

ois.readUTF() を ois.readObject() に置き換えて、文字列にキャストします。

String name = (String) ois.readObject();

コンパイル/試していません...

于 2012-11-01T15:14:16.220 に答える