ObjectOutputStream, zapis na koniec pliku

0

mam taki kod:

		 try {
		        FileOutputStream fos = new FileOutputStream("scores.dat");
		        GZIPOutputStream gzos = new GZIPOutputStream(fos);
		        ObjectOutputStream out = new ObjectOutputStream(gzos);
		        
		        out.writeObject(score);
		        
		        out.flush();
		        out.close();
		     }
		     catch (IOException e) {
		         System.out.println(e); 
		     }

problem w tym, ze to czysci plik. jesli pare razy cos do niego wpisze i potem chce odczytac to dostane tylko jeden obiekt. jak dopisywac obiekty na koncu pliku?
czy moze jest na to jakas lepsza metoda, bo score ma zawsze taki sam rozmiar.

dzieki
pozdr [browar]

0

Zapisuj do pliku "scores.dat" kolekcję (ArrayList,Vector,...) wyników. Przy uruchamianiu programu odczytuj kolekcję z pliku "scores.dat", każdy wynik, który chcesz zapisać dołącz do kolekcji.

0

Czy nikt juz nie zaglada do dokumnetacji?
Zajrzyj jakie konstruktory ma FileOutputStream, i dodaj API do ulubionych.

0

@malamyga, ja zaglądam, nie wiedziałem jak czytać wiele obiektów z jednego pliku. Napisałem programik testowy

import java.io.*;

public class ManyObjects
{
    public static void main(String[] args)
    {
        boolean pisz=true;
        if(args.length>0)
        {
            pisz=false;
        }
        new ManyObjects(pisz);
    }
    //------------------------
    public ManyObjects(boolean pisz)
    {
        if(pisz)
        {
            String plik="Persons.dat";
            try
            {
                FileOutputStream f=new FileOutputStream(plik,true);
                ObjectOutputStream str=new ObjectOutputStream(f);
                str.writeObject(new Person("Kowalski",33));
                str.writeObject(new Person("Nowak",44));
                str.flush();
                f.close();
            }
            catch(IOException e)
            {
                System.out.println(e);
            }
        }
        else
        {
            String plik="Persons.dat";
            try
            {
                FileInputStream f=new FileInputStream(plik);
                ObjectInputStream str=new ObjectInputStream(f);
                boolean przeczytane=false;
                while(!przeczytane)
                {
                    Person p=(Person)str.readObject();
                    if(p==null)
                    {
                        przeczytane=true;
                    }
                    else
                    {
                        System.out.println(p.getName());
                    }
                }
                f.close();
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
        }
    }
}
//------------------------------------------------
class Person implements Serializable
{
    private String name;
    private int wiek;
    //-----------------------
    Person(String name,int wiek)
    {
        this.name=name;
        this.wiek=wiek;
    }
    //------------------------
    public String getName()
    {
        return name;
    }
}

i spotkała mnie niespodzianka, po kolejnych wywołaniach

java ManyObjects
java ManyObjects w

zobaczyłem (zgodnie z oczekiwaniami)

Kowalski
Nowak
java.io.EOFException

natomiast po usunięciu pliku "Persons.dat" i wywołaniach

java ManyObjects
java ManyObjects
java ManyObjects w

zobaczyłem takie coś (plik "Persons.dat" był teraz dwa razy większy)

Kowalski
Nowak
java.io.StreamCorruptedException: invalid type code: AC

Co robię źle ?

0

Zmieniłem fragment zapisujący na poniższy i działa dobrze.

 ArrayList<Person> persons=new ArrayList<Person>();
 try
 {
       FileInputStream f=new FileInputStream(plik);
       ObjectInputStream str=new ObjectInputStream(f);
       boolean przeczytane=false;
       while(!przeczytane)
       {
             Person p=(Person)str.readObject();
             if(p==null)
                   przeczytane=true;
             else
                    persons.add(p);
        }
        f.close();
}
catch(Exception e)
{
       System.out.println(e);
}
try
{
        FileOutputStream f=new FileOutputStream(plik);
        ObjectOutputStream str=new ObjectOutputStream(f);
        str.writeObject(new Person("Kowalski",33));
        str.writeObject(new Person("Nowak",44));
        for(int i=0;i<persons.size();i++)
        {
            str.writeObject(persons.get(i));
        }
        str.flush();
        f.close();
}
catch(Exception e)
{
       System.out.println(e);
}

@mamalyga, twoje rozwiązanie jest chyba niedobre.

0

@bogdans
nie pisalem do Ciebie, tylko do autora watku, API ma odpowiedz na jego pytanie :-) domyslam sie ze Ty czytasz API

Twojego kodu nie przegladalem, ale na pewno jest dobrze
pozdrawiam

0
package test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Test {

    public static void main(String[] args) {
        boolean pisz = true;
        if (args.length > 0) {
            pisz = false;
        }

        String plik = "Persons.dat";
        try {
            FileOutputStream f = new FileOutputStream(plik, true);
            ObjectOutputStream str = new ObjectOutputStream(f);
            str.writeObject("Kowalski");
            str.writeObject("Nowak");
            str.flush();
            str.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Troszke przerobiony kod Bogdansa.
Wywolaj kod lilka razy, po kazdym razie otworz plik "Persons.dat" w notatniku, albo sprawdzaj jego rozmiar. Za kazdym razem bedzie to wielokrotnosc bajtow po pierwszym zapisie (u mnie 23, 46, 69 itd).
Pytanie bylo: jak zapisac do pliku przyrostowo, aby nie nadpisywac za kazdym razem zawartych w nim juz danych, i konstruktor o ktorym wspomnialem dziala jak nalezy.
Pozdrawiam.

0

@malamyga, może na Stringach działa dobrze, na obiektach klasy Person działa źle, sprawdź.
//edit Na Stringach też działa źle. szkoda że nie przeczytałeś mojego postu. Pisałem że dopisywanie działa ale odczytanie nie działa jeżeli dopisywanie odbywało się w dwóch sesjach.

0

Racja dziala zle, pewnie dla stringow tez. Chodzio to ze zapisuje 2 razy tak jak powinien, ale przy serializacji zapisuje sie tez klase obiektu ktory jest serializowany. Tutaj zapisywana ona jest 2 razy, dlatego wczytanie tego co zapisalo sie drugi raz zwraca blad. Czyli ze zapisuje dokladajac dane do pliku, ale nie umie ich pozniej odczytac, lipa :D

0

Kilka postów wcześniej podałem rozwiązanie problemu:

  • przed zapisem odczytujemy wszystkie obiekty z pliku do jakiejś kolekcji
  • otwieramy plik do zapisu w trybie not append
  • zapisujemy wszystko z kolekcji
  • dopisujemy nowe obiekty
    Kolejność ostatnich dwóch kroków może być odwrotna.
    pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1