Posiadam plik z serializowanymi obiektami mojej klasy.
Chciałbym je odczytać tylko, że nie wiem ile tych obiektów tam zostało zapisanych. I teraz mam problem, jak określić ile tych obiektów ktoś tam wcześniej zapisał by wszystkie odczytać.
Co dokładnie serializujesz? Jeżeli jest to lista obiektów to nie musisz znać rozmiaru, po prostu deserializujesz jako listę.
Jeśli chcesz odczytać nieznaną Ci ilość obiektów to zrób for'a który odczytuje kolejno element po elemencie i umieszcza go na arraylist. Później konwertujesz arraylist'a na tablicę i proszę. Masz tablicę wszystkich obiektów.
@niezalogowany
Próbowałem serializować całą listę obiektów ale mam problem z deserializowaniem całej listy, nie do końca wiem jak to zrobić.
Serializując przekazywałem całą listę jako argument funkcji writeObject(savedObcject);
public void saveSF(ArrayList<? extends Object> savedObcject, String patch){
try {
saveFile = new FileOutputStream(patch);
objectOutFile = new ObjectOutputStream(saveFile);
objectOutFile.writeObject(savedObcject);
objectOutFile.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
Ale deserializując nie mogę po prostu użyć funkcji readObject();
public ArrayList<Object> loadSerialFile(String patch) {
File loadFile = new File(patch);
ArrayList<Object> loadData;
if (loadFile.exists()) {
try {
this.loadFile = new FileInputStream(loadFile);
objectInFile = new ObjectInputStream(this.loadFile);
loadData = objectInFile.readObject();
objectInFile.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
return loadData;
}
} else {
//
return loadData;
}
}
W pętli while(true) wywołuj readObject(), koniec pliku poznasz po tym, że readObject() rzuci EOFException.
@bogdans
Zapomnaiłem rzutować na ArrayList<Object> i dlatego niechciało mi iść, poradziłem sobie już z tym tylko teraz wyświetla mi dwa ostrzeżenia:
Warning:java: /home/sougo/IdeaProjects/lFileTest/src/Test2.java uses unchecked or unsafe operations.
Warning:java: Recompile with -Xlint:unchecked for details.
To jest jedno ostrzeżenie, skompiluj z opcją -Xlint, to się dowiesz o co chodzi.
Obawiam się, że tego ostrzeżenia nie można się pozbyć.
@bogdans
Bo skompilowaniu z parametrem -Xlint pokazało mi:
Test2.java:14: warning: [unchecked] unchecked cast
dataARC = (ArrayList<DataARC>)loadSerialFile.loadSerialFile("/home/sougo/lib/file.l");
^
required: ArrayList<DataARC>
found: ArrayList<CAP#1>
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ? extends Object
./LoadSerialFile.java:26: warning: [unchecked] unchecked cast
loadData = (ArrayList<Object>)objectInFile.readObject();
^
required: ArrayList<Object>
found: Object
./LoadSerialFile.java:37: warning: [finally] finally clause cannot complete normally
}
^
Udało mi się pozbyć tego ostrzeżenia.
Deserializowaną listę przypisywałem do ArrayList<Object> i przez to pokazywało się to ostrzeżenia jak zmieniłem na ArrayList<? extends Object> to zniknęło ono.
A co złego w tym ostrzeżeniu? Ostrzeżenie zlikwidowałeś, ale problemu nie. Co się zdarzy gdy na skutek swojej pomyłki lub czyjegoś sabotażu w deserializowanym pliku będzie obiekt typu np. JFrame? Rzutowanie
(ArrayList<...>)objectInFile.readObject();
wygeneruje nieobsługiwany wyjątek.
@bogdans
Nie dopisałem tych stringów na końcu nad pisało tamten listą trzech obiektów typu string. I po uruchomieniu programu wczytującego wyrzuciło mi:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to DataARC
at Test2.main(Test2.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
a ta 15 linia w której dopiero zgłosiło ten wyjątek to:
System.out.println(dataARC.get(0).getPositiondoor());
Pokaż cały plik Test2.java. Komunikat java.lang.ClassCastException
mówi wyraźnie o błędzie rzutowania.
public class Test2 {
public static void main(String arg[]){
LoadSerialFile loadSerialFile = new LoadSerialFile();
ArrayList<DataARC> dataARC;
dataARC = (ArrayList<DataARC>)loadSerialFile.loadSerialFile("/home/sougo/lib/file.l");
System.out.println(dataARC.get(0).getPositiondoor());
System.out.println(dataARC.get(1).getPositiondoor());
System.out.println(dataARC.get(2).getPositiondoor());
System.out.println(dataARC.get(3).getPositiondoor());
}
}