Odczyt zserializowanego obiektu z pliku

0

Jak odczytać cały plik zapisany poprzez serializację.

public static Person importData() throws IOException, ClassNotFoundException {

  try (
          var read = new FileInputStream(filename);
          var ois = new ObjectInputStream(read);
  ) {


      return (Person) ois.readObject();

Pokazuje tylko ostatni wpis.

0

Nie zadanie szkolne. Tak dla testów.
Po każdym dodaniu Person plik się powieksza.
W main mam dla testów person1 person2.
Zaraz wrzucę kod, ale to tylko 3 klasy
Person, Writer i Main

0

Gdyby było tam coś innego niż ten "ostatni wpis", to ten kod zwracałby błąd, a z tego co piszesz, to nie pokazuje. Pokaż lepiej jak ten plik tworzysz, to może coś się da rozkminić.

0
public static void  exportData(Person person) throws IOException {
  try (
          var fos = new FileOutputStream(filename,true);
          var oos = new ObjectOutputStream(fos);
  ) {
    oos.writeObject(person);
  }

W main

  Person person1 = new Person("a88z", "uuuuu", 88);
  Person person2 = new Person("aaaaa", "zzzzz", 56);
   
  Writer.exportData(person1);
  Writer.exportData(person2);
   
  System.out.println(Writer.importData());//  post pierwszy.
}

Wynik Person{firstName='a8888z', lastName='uuuuu', wiek=88} //wczesniej wprowadzone dane

Jeśli var fos = new FileOutputStream(filename,true); wykasuje flage true

Person{firstName='aaaaa', lastName='zzzzz', wiek=56} plik automatycznie sie zmniejsza

1

Przecież wrzucasz dane do strumienia utworzonego z parametrem append, czyli dopisz na końcu. Chyba normalne, ze plik się zwiększa? Próbowałeś wywołać kilkukrotnie readObject()?

0

Tak normalne że sie zwieksza tylko odczytuje pierwszy wpis. Czyli wywołać readObject() w return (Person) ois.readObject(); Jeśli tak, to jak miało by to wygladać?

2
public class Main {

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {
        final String a = "a";
        final String b = "b";

        final ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./data.bin", true));

        objectOutputStream.writeObject(a);
        objectOutputStream.writeObject(b);

        objectOutputStream.close();

        final ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("./data.bin"));

        System.out.println(objectInputStream.readObject());
        System.out.println(objectInputStream.readObject());

        objectOutputStream.close();

    }
}
0

Dzięki.

1

Tak a propos, mało kto dziś interesuje się tradycyjną javowską serializacją. Zadanie szkolne ? — ZrobieDobrze dziś, 12:45

Mało bo? — marian pazdzioch dziś, 19:58

Jest używana, i ma swoją MOCNA pozycję w specjalistycznych miejscach. Np nie zbudujesz cache bez fajnej binarnej serializacji obiektów javowskich (i trwa wyścig implementacji serialziacji binarnych, krio, takie, siakie).

A lud serializuje do JSON-a czy XML-a

0
bbzzyyczczeek napisał(a):

Tak normalne że sie zwieksza tylko odczytuje pierwszy wpis. Czyli wywołać readObject() w return (Person) ois.readObject(); Jeśli tak, to jak miało by to wygladać?

W pierwszym poście dałeś "ostatni zapis".
To ważna mylna wskazówka

0

Moja pomyłka sorry. A istnieje jakiś warunek do petli coś jak w bufferReader nextLine!=null

2

Nie wiem, pewnie wyleci jakieś określone exception - sprawdź. A z drugiej strony, to dlaczego nie serializujesz ArrayList<Person>?

0

Ale muszę też jakoś odczytać plik. I o ile Twój sposób jest dobry jeśli znamy ilość obiektów do odczytania to jak nie wiemy lub się zmiei ilość?

1
bbzzyyczczeek napisał(a):

Ale muszę też jakoś odczytać plik. I o ile Twój sposób jest dobry jeśli znamy ilość obiektów do odczytania to jak nie wiemy lub się zmiei ilość?

Ze staranniejszą interpunkcją byłbyś lepiej rozumiany. Pomyśl o tym.

Serializowanie kolekcji (@piotrpo ) to naprawdę dobry pomysł - obsługę ilości zwalasz na silnik

2

No właśnie "mój sposób" jest dobry, bo nie musimy znać liczby obiektów do odczytania, jak są różne typy tych obiektów, to też nie musimy wiedzieć jakie są typy itd. Tworzysz sobie jakiś model danych typu:

public class MyApplicationData implements Serializable{
//serializable id - nie pamiętam jak miał się nazywać ten dziwaczny UUID...

  private List<Person> persons;
  private List<Car> cars;
  private List<CarUsageRecord> carUsageRecords;

  ....

}

Wypełniasz danymi, serializujesz, później deserializujesz i masz wszystko załatwione. Pomijając dostępność definicji klas Person, Car, CarUsageRecord w class path, nie musisz wiedzieć ile jakich obiektów tam się znajduje.
Jedyne pytanie, to czy faktycznie aż tak bardzo potrzebujesz wydajności podczas serializacji, żeby pozbawić się atutów w postaci czytelności zawartości tego co jest w pliku, większej elastyczności zmian struktury tej "bazy danych".

0

Nie chodzi o wydajność , tak jak pisałem wcześniej. To tylko dla testu.
Dziękuje i Pozdrawiam

1
bbzzyyczczeek napisał(a):

Nie chodzi o wydajność , tak jak pisałem wcześniej. To tylko dla testu.
Dziękuje i Pozdrawiam

Propozycja Piotra jest ze wszech miar prawidłowa, i jak się uczysz to właśnie jest prawidłowa

Np deserializacja to dość subtelna czynność odtworzenia grup obiektów w swoich powiązaniach, i TYLKO w jednej czynności masz to zagwarantowane.
Sekwencja wielu niezależnych (de)serialziacji da błędne wyniki - np wiele egzemplarzy signletona (cyt chyba za Jarkiem R )

Twoje próby (de)serializacji w pętli są wbrew "dobrym praktykom serializacji" - to make long story short - źle się uczysz.

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