Pętla z deserializacją wykonuje się tylko raz

0

Męczę się z deserializacją obiektów w pętli. Mimo, że w pliku zaserializowałem więcej obiektów niż jeden, to pętla deserializuje tylko pierwszy obiekt i wywala wyjątek StreamCorruptedException(: invalid type code: AC) dla linii:

Movie movie = (Movie) ois.readObject();
static void loadMovieFromDataBase(List<Movie> list) {
		try {
			FileInputStream fis = new FileInputStream("movies.ser");
			ObjectInputStream ois = new ObjectInputStream(fis);
			
			while(fis.available() > 0) {
				Movie movie = (Movie) ois.readObject();
				list.add(movie);
			}
			
			ois.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
0

Pokaż kod serializujący.

0
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("movies.ser", true));
				oos.writeObject(obj);
				oos.close();

A to klasa Movie

import java.io.Serializable;

/**  Object class film */
public class Movie implements Serializable {
	private static final long serialVersionUID = 1L;
	
	/**  Title of the movie */
	private String title;
	/**  Movie description */
	private String description;
	/**  The film's director */
	private String director; 
	/**  Movie Release Date */
	private String releaseDate;
	/**  Film genre */
	private String genre;
	/**  Country of production */
	private String country;
	/**  The film's budget */
	private int budget;
	/**  Rating movie */
	private int rate;
	
	public Movie() {}
	
	public Movie(String title, String description, String director, String releaseDate, String genre, String country,
			int budget, int rate) {
		
		this.title = title;
		this.description = description;
		this.director = director;
		this.releaseDate = releaseDate;
		this.genre = genre;
		this.country = country;
		this.budget = budget;
		this.rate = rate;
	}
	
	public String toString() {
		return "Title: " + title + " Director: " + director + " Rate: " + rate;
	}
}
0

Nie możesz dopisywać obiektów do pliku. Masz dwie możliwości:

  • zapisać w jednej pętli wszystkie obiekty,
  • zapisać kolekcję (listę obiektów).
0

Dyskusję (pytania) prowadź w wątku, nie w komentarzach.

ObjectOutputStream oos = new ObjectOutputStream(f);
oos.writeObject(list);
...
ObjectInputStream ois = new ObjectInputStream(f);
list = (List) ois.readObject();
0

Mam teraz taki kod:

List<Movie> list = new ArrayList<Movie>();
					
					FileInputStream fis = new FileInputStream("movies.ser");
					ObjectInputStream ois = new ObjectInputStream(fis);
					
					list = (List<Movie>)ois.readObject();
					list.add((Movie) obj);
					
					ois.close();
					
					ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("movies.ser"));
					oos.writeObject(list);
					
					oos.close();

i linia

ObjectInputStream ois = new ObjectInputStream(fis);

wyrzuca wyjątek. A muszę mieć tutaj taki kod, bo program polega na dodawaniu filmów do pliku, więc chcę wczytać najpierw listę tych istniejących plików, potem dodać do tej listy ten co dopiero uzupełniłem danymi i tą listę z nowo dodanym obiektem znowu zaserializować.

0

Jaki wyjątek.
Druga sprawa, nie możesz wykorzystać pliku movies.ser utworzonego poprzednią wersją programu. Z niego odczytasz inny obiekt - film, a nie listę filmów.

0

java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at Database.serialization(Database.java:183)
at Database.addToDatabase(Database.java:158)
at Database.main(Database.java:83)

Po zmianie kodu wyczyściłem plik. Jest na razie pusty, bo właśnie nie mogę nić dodać przez te błędy.

0

Omg, Ty chcesz zapisać do pliku korzystając z kodu

                    FileInputStream fis = new FileInputStream("movies.ser");
                    ObjectInputStream ois = new ObjectInputStream(fis);

To Ci się na pewno nie uda.
Musisz wpierw zapisać korzystając z ObjectOutputStream.

0

Nie, ja chcę najpierw wczytać, aby dodać do tej listy nowy obiekt i z nowo dodanym obiektem zapisać do pliku.

0

Chcesz wczytać z pustego pliku, czy z pliku utworzonego poprzednią wersją programu. Ani jedno, ani drugie się nie uda. Napisałem

Musisz wpierw zapisać korzystając z ObjectOutputStream

0

No tak. Chcę wczytać pusty plik, ale to nie ma chyba znaczenia, bo błąd wywala już na 'ObjectInputStream ois = new ObjectInputStream(fis);', a tutaj jeszcze nic nawet nie wczytuję.

0

Mylisz się, ma znaczenie.

0

W taki razie to ja nic nie wiem. Mógłbyś mi wytłumaczyć?

0

Co tu jest do tłumaczenia?
Już dwa razy Ci pisałem, że masz zacząć od zapisania do pliku movies.ser jakiejś listy filmów. A ty uparcie zaczynasz od odczytania.

0

Dobra. Zrobiłem tak jak pisałeś. Musiałem stworzyć pomocniczy plik w którym zapisuję ilość filmów, aby gdy plik jest pusty wykonywały się kokretne operacje. Ale mam jeszcze problem z odczytem tej listy. Mam

static void showDatabase(int index) {
		if(index == 1) {
			List<Movie> movies = new ArrayList<Movie>();
			
			loadMovieFromDataBase(movies);
			
			for(Movie movie : movies) {
				System.out.println((movies.indexOf(movie)+1) + ". " + movie.toString());
			}
		}
	}
	
	static void loadMovieFromDataBase(List<Movie> list) {
		try {
			FileInputStream fis = new FileInputStream("movies.ser");
			ObjectInputStream ois = new ObjectInputStream(fis);
			
			while(fis.available() > 0) {
				list = (List<Movie>) ois.readObject();
			}
			
			ois.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

Wydawało mi się, że przesyłanie listy odbywa się tak samo jak tablicy. Ale po uzupełnieniu tablicy w loadMovieFromDataBase, w showDatabase już w tej liście nie ma tych obiektów.

0

A do pliku movies.ser zapisałeś jakąś listę?
Przy okazji, w tym pliku będzie tylko jeden obiekt (lista filmów). Nie potrzebujesz żadnej pętli do odczytu.
Program by się uprościł, gdyby lista filmów była polem w klasie. Nie trzeba by jej było przekazywać jako parametru.
Napisałeś

Musiałem stworzyć pomocniczy plik w którym zapisuję ilość filmów
Po co Ci ten plik, sprawdzaj czy plik movies.ser istnieje.

if(!new File("movies.ser").exists())
{
   //utworzenie nowej pustej kolekcji
}
else
{
   //odczytanie kolekcji
}

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