Soru Java seri hale getirilmiş nesneleri bir dosyaya nasıl yazılır ve okunur


Bir dosyaya birden çok nesne yazacağım ve daha sonra bunları kodumun başka bir bölümüne geri alacağım. Kodumda hata yok, ancak düzgün çalışmıyor. Kodumun nesi yanlış olduğunu bulmama yardım eder misin? Farklı web sitelerinden farklı kodları okudum ama hiçbiri benim için çalışmadı!

Benim nesneleri bir dosyaya yazmak için kodum: MyClassList, sınıfımın (bir dosyaya yazılması gereken) nesneleri içeren bir arraylisttir.

for (int cnt = 0; cnt < MyClassList.size(); cnt++) {
    FileOutputStream fout = new FileOutputStream("G:\\address.ser", true);
    ObjectOutputStream oos = new ObjectOutputStream(fout);
    oos.writeObject(MyClassList.get(cnt));
}

Çıktı akışının yapıcısına "doğru" ekledim, çünkü her bir nesneyi dosyanın sonuna eklemek istiyorum. Bu doğru mu?

Ve buradaki nesneleri okumak için benim kodum:

 try {
     streamIn = new FileInputStream("G:\\address.ser");
     ObjectInputStream objectinputstream = new ObjectInputStream(streamIn);
     MyClass readCase = (MyClass) objectinputstream.readObject();
     recordList.add(readCase);
     System.out.println(recordList.get(i));
 } catch (Exception e) {
     e.printStackTrace();
 }

Sonunda sadece bir nesne basıyor. Şimdi, doğru yazmıyor veya doğru okuma yapmıyorum bilmiyorum!


43
2018-06-25 09:43


Menşei


olası kopyası Java'daki bir dosyadan nesneleri serileştirme - Ajay George
Nesneleri bir döngüde yazarsınız, fakat onları bir döngü içinde okumazsınız ...? - Sikorski
Sınıfınız MyClass seri hale getirilebilir mi? - morgano
En azından özel önlemler almadan ObjectOutputStream ile yazılmış bir dosyaya ekleyemezsiniz. Ancak aynı dosyayı bir döngüde açmaya ve kapatmaya gerek yok. - user207421
Kurucudaki Boolean değeri otomatik deşarj içindir, bunu true olarak ayarladığınızda, her seferinde "fout.flush ()" yazmanız gerekmez. - BilalDja


Cevaplar:


Neden tüm listeyi bir seferde serileştirmiyorsunuz?

FileOutputStream fout = new FileOutputStream("G:\\address.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(MyClassList);

Tabii ki, MyClassList bir olduğunu varsayarsak, ArrayList veya LinkedList, veya başkası Serializable Toplamak.

Geri okumak durumunda, kodunuzda sadece bir öğe hazırsınız, yazılan tüm öğeyi toplamak için bir döngü yoktur.


57
2018-06-25 09:47



Fout ve oos kapatmayı unutmayın! [Fout.close (); oos.close ();] - wea
@ user1419243 Eğer bu cevap sorununuzu çözmüşse, onay işaretini tıklatarak kabul etmelisiniz. - likejiujitsu
@likejiujitsu, bildiriminiz için teşekkür ederim. Cevap kabul edileni olarak işaretlemeyi unutmuştum. - user1419243
Bunu kullanarak performansı büyük ölçüde geliştirilebilir. BufferedOutputStream arasında FileOutputStream ve ObjectOutputStream. - Augustin
Soru okuma ve yazma ile ilgilidir, ancak bu cevap sadece yazıyı kapsar. - User


Diğerlerinin önerdiği gibi, tüm listeyi bir seferde serileştirebilir ve seri hale getirebilirsiniz, ki bu daha basittir ve yapmak istediğiniz şeyle mükemmel bir şekilde uyumlu görünmektedir.

Bu durumda serileştirme kodu olur

ObjectOutputStream oos = null;
FileOutputStream fout = null;
try{
    fout = new FileOutputStream("G:\\address.ser", true);
    oos = new ObjectOutputStream(fout);
    oos.writeObject(myClassList);
} catch (Exception ex) {
    ex.printStackTrace();
} finally {
    if(oos != null){
        oos.close();
    } 
}

Ve serileştirme (myClassList'in bir liste olduğunu ve jenerik kullanacağınızı ümit ederek) olur:

ObjectInputStream objectinputstream = null;
try {
    FileInputStream streamIn = new FileInputStream("G:\\address.ser");
    objectinputstream = new ObjectInputStream(streamIn);
    List<MyClass> readCase = (List<MyClass>) objectinputstream.readObject();
    recordList.add(readCase);
    System.out.println(recordList.get(i));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if(objectinputstream != null){
        objectinputstream .close();
    } 
}

Ayrıca, aşağıdaki amaçlarla kullandığınız gibi bir dosyadan birkaç nesneyi de kaldırabilirsiniz:

ObjectInputStream objectinputstream = null;
try {
    streamIn = new FileInputStream("G:\\address.ser");
    objectinputstream = new ObjectInputStream(streamIn);
    MyClass readCase = null;
    do {
        readCase = (MyClass) objectinputstream.readObject();
        if(readCase != null){
            recordList.add(readCase);
        } 
    } while (readCase != null)        
    System.out.println(recordList.get(i));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if(objectinputstream != null){
        objectinputstream .close();
    } 
}

Lütfen sonuncu maddede akış nesnelerini kapatmayı unutmayın (not: istisna atabilir).

DÜZENLE

Yorumlarda önerildiği gibi, kullanılması tercih edilmelidir kaynaklarla denemek ve kod oldukça basit olmalı.

İşte liste serileştirme:

try(
    FileOutputStream fout = new FileOutputStream("G:\\address.ser", true);
    ObjectOutputStream oos = new ObjectOutputStream(fout);
){
    oos.writeObject(myClassList);
} catch (Exception ex) {
    ex.printStackTrace();
}

42
2018-06-25 12:15



Try / catch uygulandığından beri kabul edilen cevap olmalı - starscream_disco_party
Java 8 kullanıyorsanız, kaynakları kullanarak deneyin - zurbergram
@zurbergram Haklısınız ve tercih edilir. Bu cevabı yazdığım sırada kullanma fırsatım olmadı - C.Champagne


Her bir nesneyi kendi bir Dosyaya yazman gerektiğini veya okurken onu ayırmanız gerektiğini düşünüyorum. Listenizi serileştirmeyi ve seri hale getirme sırasında da almayı deneyebilirsiniz.


0
2018-06-25 09:50





Tüm listeyi serileştirirseniz, geri okurken dosyayı bir listeye de serileştirmeniz gerekir. Bu, kaçınılmaz olarak belleğe büyük bir dosya yükleyeceğiniz anlamına gelir. Pahalı olabilir. Büyük bir dosyanız varsa ve satır satır satır (sadece nesneyi nesne ile) ilk fikrinle devam et.

Serile:

LinkedList<YourObject> listOfObjects = <something>;
try {
    FileOutputStream file = new FileOutputStream(<filePath>);
    ObjectOutputStream writer = new ObjectOutputStream(file);
    for (YourObject obj : listOfObjects) {
        writer.writeObject(obj);
    }
    writer.close();
    file.close();
} catch (Exception ex) {
    System.err.println("failed to write " + filePath + ", "+ ex);
}

De-serileştirme:

try {
    FileInputStream file = new FileInputStream(<filePath>);
    ObjectInputStream reader = new ObjectInputStream(file);
    while (true) {
        try { 
            YourObject obj = (YourObject)reader.readObject();
            System.out.println(obj)
        } catch (Exception ex) {
            System.err.println("end of reader file ");
            break;
        }
    }
} catch (Exception ex) {
    System.err.println("failed to read " + filePath + ", "+ ex);
}

0
2018-05-23 10:53