Checking if a file exists - strange runtime error

I’m trying to write a routine that will load from a user’s file (required filename is, say “My patches.txt”) in the data folder but that will default to another file if the user’s file does not exist. I found the ‘file exists test’ below on the forum and it works fine except if the filename differs only due to a difference in upper or lower case.

UsersFile and filename are (global) defined earlier as

String filename = null;
...
String UsersFile = "My patches.txt";
  1. If the user’s file does not exist then the default file is read in correctly
  2. If the user’s file does exist and matches “My patches.txt” exactly then the user’s file is read correctly
  3. If the user’s file exists but is named, say, “my patches.txt” (just a difference in lower versus upper case) I get the following runtime error

RuntimeException: This file is named my patches.txt not F:\Arduino\BNLibrarian_5_03_BETA_V5_Emulations\data\My patches.txt. Rename the file or change your code.

void loadPresets() {
  BufferedReader reader; 
  String line; 
 
  // See if the user's file exists

  File f = dataFile(UsersFile);
  String filePath = f.getPath();
  boolean exists = f.isFile();
  println(filePath, exists);


  if (exists) {
    filename = dataPath(UsersFile); // Try to load the user's own file first, if that fails load our default
    println(filename);
    reader = createReader(filename);
    println("reader = " + reader);
  } else {
    filename = dataPath("V5 Blue Nebula Patches.txt"); // dataPath("name") returns the full filepath to the file 'data/name'. dataPath() returns the path to the 'data' folder
    println(filename);
    reader = createReader(filename);
  }

I can only assume createReader() is case-sensitive to the filename whereas dataFile() is case-insensitive but I can’t figure out how to get around this problem. Any help would be greatly appreciated.

Thanks, Phil.

1 Like

I’m pretty sure File has an exists() method. Try that instead of isFile().

You’re correct, File does have an exists() method but that gives the same runtime error, sadly :thinking:

Phil

createReader takes the path of the file based on the data folder. Instead of passing it filename, pass it UsersFile.

reader = createReader(UsersFile);

Thanks again Schred - I didn’t realize that createReader() takes the path to the data folder. I tried your suggestion.

  File f = dataFile(UsersFile);
  String filePath = f.getPath();
  boolean exists = f.exists();
  println(filePath, exists);


  if (exists) {
    filename = dataPath(UsersFile); // Try to load the user's own patches first, if that fails load ours
    println(filename);
    reader = createReader(UsersFile);
    println("reader = " + reader);
  } else {
    filename = dataPath("V5 Blue Nebula Patches.txt"); // dataPath("name") returns the full filepath to the file 'data/name'. dataPath() returns the path to the 'data' folder
    println(filename);
    reader = createReader("V5 Blue Nebula Patches.txt");
  }

Now the runtime error is slightly different. It doesn’t refer to the full path, instead I get:

RuntimeException: This file is named my patches.txt not My patches.txt. Rename the file or change your code.

Still seems very strange that the runtime thinks the two filenames are different.

Phil.

Huh. That is very strange indeed. Looks like you’ll need your own exists() method that is case sensitive:

void setup() {
  String fileName = "My patches.txt";

  if (fileExistsCaseSensitive(fileName)) {
    println("'" + fileName + "' exists.");
    createReader(fileName);
  } else {
    println("'" + fileName + "' does not exist");
  }
}

boolean fileExistsCaseSensitive(String fileName) {
  File dataFolder = new File(dataPath(""));

  for (File file : dataFolder.listFiles())
    if (file.getName().equals(fileName))
      return true;

  return false;
}

Note: This only works for files that are directly in the data directory (not sub-folders), but that shouldn’t be too difficult to implement if you need it. ;D

2 Likes

That works beautifully! Thank you so much Schred :vulcan_salute:

The case-sensitivity must be in the underlying java file handling somewhere. I’m aware of this causing problems moving apps from Windows (case-insensitive) to Linux (case-sensitive).

By the way there’s a small typo in your code that you might want to fix for others finding your solution here: you have createrReader(filename) should of course be createReader(filename) :slightly_smiling_face:

Thanks again!

Phil.

2 Likes

You’re welcome! And thanks for telling me about the typo. ;D