Java serialization not writing to file - java

I have tried to serialize an object of type
HashMap<UUID, ArrayList<String>>
Knowingly, Hashmap is Serializable, UUID, ArrayList, and String are too.
I have debugged the value of the map, and the path, they're correct, no error is throws and the code seems to successfully run, however nothing is being written into the file...
Here's the code:
try
{
FileOutputStream fos = new FileOutputStream(file.getPath());
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(serializable);
oos.close();
fos.close();
System.out.println("Success serialization - " + serializable + " at path " + file.getPath());
}catch(Exception e)
{
e.printStackTrace();
}
The results of the syso were valid, not a null nor an empty table, and a correct path, a file exists in that dictionary and everything...
does anyone know why it wouldn't work?
I tried googling but all I saw were cases where an error was thrown or an incorrect path was used etc...
EDIT
the "serializable" is the table. I made a serialize method taking a file and a Serializable type, and a HashMap is so it passes

Alright, I figured it out.
When I originally made the class that handled it, it also used another something that is made for something else(mostly human-readable text), which interfered with it.
I then tested by creating another class purely for serialization, and it worked!
I am sorry I bothered ya'll, and thanks for #markspace for the help!
Tho that it shouldn't have interfered.. it seems to have done it so I am glad I figured it out

Related

Looking for an explanation regarding file.delete() method in try catch block

Trying to make a simple 'cut' program to move files across folders.
After it makes a copy it should delete the source file but it ignores the fileLocation.delete(); method in the try block. If I put it in the 'finally' block it works and also anywhere else in the program after it goes through copying the file but that makes no sense for it to work that way, even if something goes wrong the source will be deleted. My question is why does it ignore it, I was unable to find answers online. Thank you.
File fileLocation = new File("C:\\fileLocation\\picture.png");
File fileDestination = new File("C:\\fileDestination\\picture.png");
try(FileInputStream input = new FileInputStream(fileLocation);
FileOutputStream output = new FileOutputStream(fileDestination)) {
byte[] buffer = new byte[1024];
int length;
while((length = input.read(buffer)) > 0) {
output.write(buffer,0, length);
}
fileLocation.delete();
} catch(IOException exc) {
System.out.println(exc.getMessage());
}
try(FileInputStream input = new FileInputStream(fileLocation);
... ) {
// ..
fileLocation.delete();
}
At this point, input is still open, so you can't delete the file it refers to.
According to the definition of try-with-resources in the language spec, a finally block on a try-with-resources statement will be executed after the resource is closed. As such, putting the delete in the finally block means it can succeed.
Rather than putting it in the finally (which occurs whether or not an exception is thrown), you can split up the resources into two try-with-resources blocks, and delete once you're done with input:
try (FileOutputStream output = ...) {
try (FileInputStream input = new FileInputStream(fileLocation)) {
// ..
}
// input is now closed.
fileLocation.delete();
} catch(IOException exc) {
System.out.println(exc.getMessage());
}
Now, fileLocation is only deleted when no IOException is thrown from any preceding statement in the output try-with-resources block (including the input try-with-resources block).
Or, if you want not to delete it until output is closed: move the IOException catch into a surrounding try/catch (not try-with-resources) block:
try {
try (FileOutputStream output = ...;
FileInputStream input = ...) {
// ..
}
// input and output are now both closed.
fileLocation.delete();
} catch(IOException exc) {
System.out.println(exc.getMessage());
}
Of course, a better way to move a file would be to use the utility method to move files, e.g.
Files.move(fileLocation.toPath(), fileDestination.toPath(), CopyOption.REPLACE_EXISTING);
You're using the wrong API. File.delete() is known-bad API design.
This is what's bad about it, and why it explains your confusion: Unlike just about any other API, if delete() fails to delete, it does not throw any exceptions. Instead, it returns false. This is bad in 3 important ways:
It's un-java-like. Very few APIs do that; the vast majority of them throw something instead.
It is easy to 'forget'. Just writing x.foo(); on its own, where foo() is any method that returns something (i.e. has a non-void return type), is perfectly fine java. it's java-ese for: Run this method, then take the result and toss it in the garbage. You've done that here: Call delete() and ignore the result. For delete(), that's not actually okay unless you intended to write code that effectively means: "try to delete this path. Whether it succeeds or not, continue with the code". Which, usually, isn't what you want.
If something does go wrong, it is not possible for the delete() method to tell you any details other than 'I could not accomplish it'. No way to have a message or some sort of exception type to clear things up for you.
The solution is simple. Stop using this method. Put it on the banlist: This method should no longer ever be invoked in java code. If you are maintaining some 15 year old stuff, it's fine, I guess, but a quick refactor to get rid of it wouldn't go amiss.
Great! So what's the new one I should be using?
The path/files API in the java.nio.file package.
Replace:
File f = new File("a/b/c.txt");
f.delete();
with:
Path p = Paths.get("a/b/c.txt");
Files.delete(p);
Unlike file.delete(), Files.delete(path) WILL throw an exception if the deletion cannot be performed. This exception then contains suitable information about why. For example, because the file doesn't exist, or because you do not have write access to the underlying directory, or because the file system is mounted read only, etcetera.
The new File API is also vastly more capable. It can properly handle links or alternate file systems, for example. It also has more methods. For example, it has the Files.move method which may be of particular use here.
Just for reference, why is my delete operation failing?
Probably because your own process still has the file open. On some OS/filesystem combos (in particular, on windows and e.g. NTFS), you can't delete open files. Even if your own process is the one that still has the file open.
If you use Files.delete() you'll get an exception with a message that'll get you a lot closer to that conclusion than 'the delete() call returned false', fortunately.

ObjectInputStream Handling classNotFoundException

I have an issue while reading the data from a file using objectInputStream. Please find the code below
File file = new File("model.pst")
if (file.exists()) {
fis = new FileInputStream(file);
in = new ObjectInputStream(fis);
input = (List<GlobalModel>) in.readObject();
in.close();
}
I got to know from the ObjectOutputStream http://docs.oracle.com/javase/6/docs/api/java/io/ObjectOutputStream.html docs, that while writing the object to the file, he default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields.I have an issue where the class name has been changed after writing the object to the file and when I use the above code to read the values, its throwing a classNotFound exception. I would like to know if there is a way, I can handle this exception, i.e once it comes to the exception block, can I replace the classname in the object that is being read to the new class name and make it work ?
Please Assist. Thanks in Advance
I've never done this myself but it should be possible to replace a class by another by making a subclass of object input stream and overriding the resolveClass method, http://docs.oracle.com/javase/6/docs/api/java/io/ObjectInputStream.html#resolveClass(java.io.ObjectStreamClass)

Reading object from file using ObjectInputStream? ClassNotFoundException

In previous code in my program, I had saved an ArrayList (consisting of objects of a custom class called location as you can see in my code) in a file using ObjectOutputStream and FileOutPutStream. However, when trying to retrieve the object from the file, using ObjectInputStream, I am getting an error saying that I have an unhandled exception (ClassNotFoundException).
Here's the code I used to get the ArrayList out of the file:
String file = "file";
ObjectInputStream input = new ObjectInputStream(new FileInputStream("file"));
ArrayList<location> arrayList = new ArrayList<location>();
arrayList = (ArrayList) input.readObject();
The error is on the line where I call the .readObject() method. Any Help will be appreciated as I am new to Java. Thank You!
That means the class you sent could not be found in your app. You have to add it to the class path of the app, or only send classes the app has. In your case, the missing class will be in the ArrayList as ArrayList will always be there.
Nothing mysterious is going on, the error means just what it says.
It would be more useful if the exception told you which class was missing. I think Java 7 does this now.

Porting java application to android - is it possible to make Serializable work?

I'm attempting to port a java application to android. The application uses Serializable to store data. There's an array list of users, and each user has various other elements(all of which also implement serializable). In the java app, saving all data was simply a matter of calling a method that writes the serialized user list to a text file. This doesn't seem to work with Android.
It's not a file not found or IO exception - I took care of that already.
Any ideas on how to get around this?
public boolean loadUsers()
{
File newFile = new File("sdcard/download/users.txt");
FileInputStream fileIn = null;
try
{
fileIn = new FileInputStream(newFile);
ObjectInputStream inStream = new ObjectInputStream(fileIn);
users = (ArrayList<User>)inStream.readObject();
fileIn.close();
return true;
}
catch (FileNotFoundException e)
{
System.err.println("File not found exception...");
}
catch (IOException e)
{
System.err.println("Error occurred reading the file, aborting...");
}
catch (Exception e)
{
System.err.println("Unexpected exception...");
}
return false;
}
I've figured it out - I changed the package names, so the old serialized file isn't being read properly for that reason. Everything works fine otherwise.
A ClassNotFoundException when you are trying to deserialize objects most likely means that you don't have classes on your classpath for the objects in the serial stream. You need to add the relevant JAR file (or whatever) to the classpath. The full exception message / stacktrace will tell you which class it is missing ...
(This is not an Android-specific problem. The serialized object stream does not contain the bytecodes for the classes. The JVM needs to have those bytecodes before it can reassemble usable objects from the stream.)
I've figured it out - I changed the package names, so the old serialized file isn't being read properly for that reason.
That's right. When you change the package name, the class becomes a different class ... as far as the JVM is concerned.

How to maintain a particular value in boolean after the program has been stopped?

I have created a class variable as follows
private boolean xyz = false;
After which I am calling a method that will do some stuff and then change the value of the boolean variable to true.
Now the next time when I re-run the code the boolean value doesn't stay as true it goes back to false.
I want it to stay as true even if i close my program and then run it again later.
I want it to stay as true even if i close my program and then run it again later.
Well, that means you need to persist it somewhere.
Options include:
Somewhere online
A database
User preferences via the Preferences API
A simple file in a well-known location
Basically, you'll need to write the data out somewhere, and read it back in on start-up. It's hard to give any more specific advice without more context.
When you are exiting your program, use below to save your variable to a file in a location of your own, preferably, local directory of the program. It is called serialization.
try
{
FileOutputStream fileOut = new FileOutputStream("xyz.ser");//this saves to the directory where your program runs in
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(xyz);
out.close();
fileOut.close();
}catch(IOException i)
{
i.printStackTrace();
}
Then, when you start your program, you can read it back with below code. This is called deserialization.
try
{
FileInputStream fileIn = new FileInputStream("xyz.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
xyz = (boolean) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{// you are here if xyz.ser does not exist
i.printStackTrace();
return;
}
You also might want to check if the file was created previously, otherwise, you will catch an IOException. You can do it by creating a File object with filename xyz.ser and calling exists() on it.

Categories

Resources