local class incompatible error - java

The following code gives me the error InvalidClassException My User class implements Serializable so I'm lost. I'm trying to store list filled with User objects and then be able to read it back.
List<User> userList = new ArrayList<User>();//list used
try {
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(fileName, true));
os.writeObject(userList);
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
// input
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
userList = (List<User>) ois.readObject();
ois.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}

If you are trying to store and later retrieve a single object (a List<> in your example) in a file, you do not want to append to the file each time you write to it. Rather, you want to overwrite the file each time, with the new object.
// Write
List<User> userList = new ArrayList<User>();
try (FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(userList);
} catch (IOException e1) {
e1.printStackTrace();
}
// read
try (FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis)) {
userList = (List<User>) ois.readObject();
} catch (FileNotFoundException | IOException | ClassNotFoundException e1) {
e1.printStackTrace();
}
Notice new FileOutputStream(fileName) does not have the true argument. Using the true argument indicates you want to open the file for "append". Using false, or leaving the append argument off entirely, will open the file for "overwrite".
Notes:
I've also used the try-with-resources statement my example. This eliminates the need for explicitly closing the streams; the streams are automatically closed for you at the end of the try { } block.
I've also used the multi-catch clause, because you are not handling the 3 exceptions any differently, so it is a bit cleaner.

Related

How to check if a file already contains an object?

I am trying to add objects (people's names, phone numbers etc.) to a file and then reading it. When I run the program and add a few objects to the file, only the first object contains the header and the ones after the first one does not, which is what I want.
However, if I close the program and then rerun it, the previous objects are still there and functioning, but if I add a new object to the file, the program treats it as "the first object", so gives it a header, which causes an error when the program tries to read the information stored in the object.
This is my "add to file" code:
try {
FileOutputStream fos = new FileOutputStream("outputfile.ser", true);
oos = new ObjectOutputStream(fos);
}
catch (NotSerializableException e1) {
System.out.println("An object was not serializable, it has not been saved.");
e1.printStackTrace();
}
catch (IOException e1) {
e1.printStackTrace();
}
JButton btnAddContact = new JButton("Add Contact");
btnAddContact.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Address newContact = new Address(firstNameTextField.getText(), lastNameTextField.getText(), homePhoneNumberTextField.getText(), mobilePhoneNumberTextField.getText(), addressTextArea.getText(), emailTextField.getText());
try {
oos.writeObject(newContact);
}
catch (IOException e1) {
System.out.println("An object was not serializable, it has not been saved.");
e1.printStackTrace();
}
dispose();
firstNameTextField.setText("");
lastNameTextField.setText("");
homePhoneNumberTextField.setText("");
mobilePhoneNumberTextField.setText("");
addressTextArea.setText("");
emailTextField.setText("");
}
});
btnAddContact.setBounds(165, 384, 110, 46);
contentPane.add(btnAddContact);
I also thought that if i checked if the file is empty or not using if (file.length() == 0) would work, but it still doesn't work. sample of my code with this implemented:
File file = new File("outputfile.ser");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
ObjectOutputStream oas = AppendingObjectOutputStream(new FileOutputStream(file, true));
if (file.length() == 0){
try {
oos.writeObject(newContact);
}
catch (IOException e1) {
System.out.println("An object was not serializable, it has not been saved.");
e1.printStackTrace();
}
} else {
try {
oas.writeObject(newContact);
}
catch (IOException e1) {
System.out.println("An object was not serializable, it has not been saved.");
e1.printStackTrace();
}
}
public class AppendingObjectOutputStream extends ObjectOutputStream {
public AppendingObjectOutputStream(OutputStream oas) throws IOException {
super(oas);
}
protected void writeStreamHeader() throws IOException {
// do not write a header, but reset:
reset();
}
}
Is there any way to solve this problem?
Your first FileOutputStream fos = new FileOutputStream(file); will overwrite any existing file.
Try at first to change it FileOutputStream fos = new FileOutputStream(file, true);.
But I discourage opening at the same time the same file. You probably need to rework the logic.

JavaFX ObjectOutputStream only returns null

I have encountered a weird behaviour of the ObjectOutputStream / ObjectInputStream.
I want to write a specific amount of Objects of the type Sitzplatz to the file belegung. So far so good. But if I try to read these Objects again they all just return null
Here is my Code:
public void getBelegtePlaetze() {
if (belegung.exists()) {
try {
FileInputStream fis = new FileInputStream(belegung);
ObjectInputStream ois = new ObjectInputStream(fis);
Sitzplatz platz = (Sitzplatz) ois.readObject();
while (platz != null) {
System.out.println(platz.getId());
platz = (Sitzplatz) ois.readObject();
}
ois.close();
fis.close();
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void speichereSitzplatzDaten() {
FileOutputStream fos;
if (!belegung.exists()) {
try {
belegung.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
try {
fos = new FileOutputStream(belegung, true);
ObjectOutputStream oos = new ObjectOutputStream(fos);
for (int i = 0; i < kundenListe.size(); i++) {
Sitzplatz platz = kundenListe.get(i).getPlatz();
platz.setId(Integer.toString(i));
oos.writeObject(platz);
}
oos.writeObject(null); // Markiert EOF
oos.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Since I have already worked with me ArrayList kundenListe quite a bit in my program, I can be 100% sure that the data in it is properly set.
I have also already used the ObjectOuputStreamin this program before and nearly copied the code, but still it does not work.
Can you tell me what I'm doing wrong?
UPDATE:
I've tried the suggestions from the comments, but I still have the same issues.
I have reduced the code to the little piece below, which should work 100%, since I have that code already in use in another class. No idea why it works in the other class and not in that one.
private File belegung = new File("belegung.kos");
public void getBelegtePlaetze() {
if (belegung.exists()) {
try {
FileInputStream fis = new FileInputStream(belegung);
ObjectInputStream ois = new ObjectInputStream(fis);
Pakett platz = (Pakett) ois.readObject();
System.out.println(platz.getId());
ois.close();
fis.close();
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void speichereSitzplatzDaten() {
FileOutputStream fos;
if (!belegung.exists()) {
try {
belegung.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
}
try {
fos = new FileOutputStream(belegung);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Pakett platz = new Pakett();
platz.setId("test");
oos.writeObject(platz);
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}

Deserialize only if a serialized file exists

I have my program setup to serialize a certain Facebook Object on exit, and deserialize it on open. But I want to have an if statement in the deserialization portion to only go on with it if a serilization file is present to avoid errors. How can I do that? Is there anyway that I could refer to the file "serilaized" and check if it exists?
Deserialization portion:
Facebook facebook = null;
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
"serialized"));
facebook = (Facebook) ois.readObject();
ois.close();
} catch (FileNotFoundException e) {
System.err.println("Could not open the file \"serialized\"");
} catch (IOException e) {
System.err.println("Could not de-serialize the object");
} catch (ClassNotFoundException e) {
System.err.println("Could not cast the de-serialized object");
}
Serialization portion:
try {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream ("serialized"));
oos.writeObject(facebook);
oos.close();
} catch (FileNotFoundException e) {
System.err
.println("Could not create the file \"serialized\"");
} catch (IOException e) {
System.err.println("Could not serialize the object");
}
The FileNotFoundException should catch the case where there is no file present to deserialize. Throwing the error is fine, so long as it is handled gracefully.

Reading from internal storage (deserialization)

I am using the following method to read from the internal storage:
private void deserialize(ArrayList<Alias>arrayList) {
try {
FileInputStream fis = openFileInput(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
arrayList = (ArrayList<Alias>)ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
It reads the content of the file "filename" to the "arrayList".
The "serialize" method is as follows:
void serialize(ArrayList<Alias>arrayList) {
FileOutputStream fos;
try {
fos = openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(arrayList);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is that I whenever I run my program again, the "arrayList" is empty. So I guess I am opening the file in wrong input mode.
My aim is to first get the array from the file, then modify it within the app, and then write the modified array back to the file.
Can someone please help me with my problem?
Thanks!
Can you post your pice of your source code? I think the way which you used to parse file content get issue.
Read here:
Android ObjectInputStream docs
I read that the method readObject() read the next object...i this that you must iterate with something like this:
MediaLibrary obj = null;
while ((obj = (MediaLibrary)objIn.readObject()) != null) {
libraryFromDisk.add(obj);
}

Java readObject previews data, but will not read or transfer it [duplicate]

This question already has answers here:
How to prevent InputStream.readObject() from throwing EOFException?
(3 answers)
Closed 9 years ago.
I can't seem to find a way to make readObject() transfer it's contents to an object variable. When I step through the Load function I get to "temp = (HashMap) ois.readObject();" Before this line is executed I am able to see the HashMap's data that I've written with oos in the expressions window of Eclipse so I know the data is there, however when this line executes I'm jumped to the IOException catch with an EOF. From what I've read this is expected, but I have not found a way to catch the EOF (loops with available() and readObjectInt() did not work). I'm running this on an Android emulator. Any suggestions would be appreciated.
public void Save(Pottylog data)
{
try
{
FileOutputStream fos = openFileOutput("Plog", Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(data.get());
oos.close();
}
catch (FileNotFoundException ex)
{
ex.printStackTrace();
}
catch (java.io.IOException e)
{
e.printStackTrace();
}
}
public HashMap<String, Integer> Load()
{
HashMap<String, Integer> temp = null;
try
{
FileInputStream fis = openFileInput("Plog");
ObjectInputStream ois = new ObjectInputStream(fis);
temp = (HashMap<String, Integer>) ois.readObject();
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
return temp;
}
EOFException means you have reached the end of the stream. I don't know what you think you're seeing in the debugger, but there is no object there in the stream to be read. catch(EOFException exc) does work; at this point you should close the stream and exit the reading loop. Don't misuse available() as an end of stream test: that's not what it's for.

Categories