javaserializationexecutable-jarserializablefile-writing

Write class objects from a running jar file to a file in another directory


Basically my program reads parameters from a class object in a memory-file at startup and if parameters are changed in the running program it overwrites memory-file and reads from it again to update parameters.

My application works as should in the IDE. Then I built my first jar from my IDE and ran it from a batch-file and it works, but not as expected.

If the memory-file exists it is reed at program startup without problem.

But when I try to change program parameters or start program without memory-file and it is supposed to overwrite the memory-file with updated class object alt. create a new, it returns "FileNotFoundException".

Here is my amateur code, I created a class with the purpose of writing/reading a "SaveClass" object to/from a text file:

public class ManageMemory {
    //filepath
    private String MEMORY_DIR = new StringBuffer(System.getProperty("user.home"))
            .append("\\Documents\\memory.txt").toString();
    private File targetFile = new File (MEMORY_DIR);

    //writes selected object to txt-file" with exceptions included
    public void writeToMemory(SaveClass object) {
        try {
            FileOutputStream f = new FileOutputStream(MEMORY_DIR);
            ObjectOutputStream o = new ObjectOutputStream(f);
            //write object to file
            o.writeObject(object);

            o.close();
            f.close();
        } catch (FileNotFoundException e) {
            System.out.println("File not found while writing");
        } catch (IOException e) {
            System.out.println("Error initializing stream");
        }
    }

    //reads current object in memory directory
    public SaveClass readFromMemory() {
        SaveClass inMemory = new SaveClass();
        if (!targetFile.exists()) {
            writeToMemory(inMemory);
        }
        try {
            FileInputStream f = new FileInputStream(MEMORY_DIR);
            ObjectInputStream o = new ObjectInputStream(f);

            inMemory = (SaveClass) o.readObject();

        } catch (FileNotFoundException e) {
            System.out.println("File not found while reading");
        } catch (IOException e) {
            System.out.println("Error initializing stream");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return inMemory;
    }
}

I have searched for information about how to approach my problem, but not found much I understand. I tested to print the canWrite() on my save file while running the .jar program and it returned true.


Solution

  • The best way to find out what’s really happening is with these steps:

    java.io.File is a very old class. It has a number of design flaws, simply because API design wasn’t as well understood in 1995.

    But the java.nio.file package is more modern and corrects all of those problems. It also has much more detailed and informative exceptions.

    Using that package looks very similar:

    public void writeToMemory(SaveClass object) {
        try (ObjectOutputStream o = new ObjectOutputStream(
            Files.newOutputStream(
                Paths.get(MEMORY_DIR)))) {
    
            //write object to file
            o.writeObject(object);
    
        } catch (IOException e) {
            System.out.println("Error initializing stream");
            e.printStackTrace();
        }
    }
    

    This will print an exception that explains exactly why the file cannot be written.

    (Notice that I am using a try-with-resources statement—that is, the ObjectOutputStream creation is inside parentheses right after try—which will automatically close the ObjectOutputStream, which in turn will close the underlying OutputStream.)