1

Im working on a Minesweeper clone and I want the user to be able to save their fastest solve times to a .txt file. I have it set up and working inside Eclipse with the following code in my i/o class:


        public static final String RECORD_FILE_NAME = "records/records.txt";

    public static String readRecords() {
        String records = "";
        
        try {
            Scanner scan = new Scanner(new FileInputStream(RECORD_FILE_NAME));
            while (scan.hasNextLine()) {
                records = records + scan.nextLine() + "\n";
            }
            scan.close();
            
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid file");
        }
        return records;
    }

    public static void writeRecords(String records, String fileName) {
        try {
            PrintStream writer = new PrintStream(new File(fileName));
            writer.print(records);
        } catch (Exception e) {
            throw new IllegalArgumentException("Unable to save file.");
        }
    }


However, after exporting the project as a Runnable JAR File, the readRecords() method throws the IllegalArgumentException from inside the catch block. So, how should I set up file i/o so that it works outside of Eclipse? Any help is greatly appreciated, thanks!

John
  • 13
  • 2
  • 1
    You're trying to write to a directory `records` relative to the "working directory". You need to beware that the working directory may or may not be the same location as the jar file and you may not have write permission at that location anyway, modern OS's can be restrictive. – MadProgrammer Apr 17 '23 at 01:35
  • One approach is to make use the platforms "common" or "well known" locations, for [example](https://stackoverflow.com/questions/27974857/where-should-i-place-my-files-in-order-to-be-able-to-access-them-when-i-run-the/27974989#27974989); [example](https://stackoverflow.com/questions/53405312/java-reading-the-properties-file-outside-of-jar-file/53405540#53405540). This places the files in a place which is independent of you applications installation location and the "working directory" – MadProgrammer Apr 17 '23 at 01:36

2 Answers2

0

A couple things to mention here:

If you want to open files safely, use a try-with-resources block

try (PrintStream writer = new PrintStream(new File(fileName))) {
    writer.print(records);
}

The way you're currently doing it may not close the file since the writer is never closed, especially if an error is thrown upon catching an exception

Second, I don't think throwing an IllegalArgumentException is optimal here since you're essentially just hiding what the may be and instead of a helpful stacktrace you get just "Unable to save file.". This is epecially problematic if something other than an IO exception is thrown, as it will just hide it (e.g. if one of those methods isn't null-safe and somehow a nullpointerexception gets thrown)

To answer your question, records/records.txt is a relative file location, and may change You'd best either go with a resource path file (extra examples) or a common file (a little less nice since it's platform-dependent), or the common locations method mentioned by MadProgrammer

Jam
  • 476
  • 3
  • 9
0

You can maybe save a text file with the needed data but this might help. This is how I store data like high scores in my game

This tutorial shows you how to create and read .txt files in Java. You could use this to read/write game data.

Here is the code from the website:

import java.io.File;  // Import the File class
import java.io.IOException;  // Import the IOException class to handle errors

public class CreateFile {
  public static void main(String[] args) {
    try {
      File myObj = new File("filename.txt");
      if (myObj.createNewFile()) {
        System.out.println("File created: " + myObj.getName());
      } else {
        System.out.println("File already exists.");
      }
    } catch (IOException e) {
      System.out.println("An error occurred.");
      e.printStackTrace();
    }
  }
}