0

My problem is associated with a function to test, whether a path contains characters that are not allowed for a given operating system. So e.g. for Windows this might be characters like '>', '|' or ':' and others (see https://msdn.microsoft.com/en-us/library/aa365247).

The code I use is basically the same as proposed on this webpage: http://eng-przemelek.blogspot.de/2009/07/how-to-create-valid-file-name.html.

private boolean testIfFileNameIsValid(String fileUri) {

    boolean invalid = true;

    try {
        File candidate = new File(fileUri);

        // Line in question:
        // If it is removed, invalid filenames will not be detected.
        candidate.getCanonicalPath();

        boolean b = candidate.createNewFile();
        if (b) {
            candidate.delete();
        }
        invalid = false;
    } catch (IOException ioEx) { }

    return invalid;
}

My problem with this code snipped is the line I marked with a comment. When this line is deleted, invalid filenames will not be discovered by the function.

So if the code is used as listed above, for example the following filename would be detected as invalid on a Windows computer:

C:\Users\Me\f:ile.txt

If this line is deleted, the above stated filename is marked as valid.

As this code does not seem to set anything, I am confused why this line has such an influence on the functions result. Could someone explain me this behaviour?

Marco N.
  • 185
  • 2
  • 8
  • [Always catch exception](http://stackoverflow.com/questions/1234343/why-are-empty-catch-blocks-a-bad-idea) – sam Oct 15 '15 at 14:03
  • Use [Path](http://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html) – Jordi Castilla Oct 15 '15 at 14:08
  • Have you noticed that your method is called testIfFileName **IsValid** () while the method returns whether it is invalid? If the method returns true, it means the filename is invalid. – Alejandro López Oct 15 '15 at 14:26
  • Yeah, my bad. In my project it is actually called slightly different, so that the return values fit better. Just renamed it for this question to indicate that it is actually the same method as was used here http://eng-przemelek.blogspot.de/2009/07/how-to-create-valid-file-name.html and as the project internal name might sound strange without additional information. I will try to watch out for such flaws in the future. – Marco N. Oct 15 '15 at 14:40

1 Answers1

0

Here is the code to getCanonicalPath()

public String More ...getCanonicalPath() throws IOException {
        if (isInvalid()) {
          throw new IOException("Invalid file path");
         }
         return fs.canonicalize(fs.resolve(this));
     }

Here is the code to the isInValid() method it is calling

final boolean More ...isInvalid() {
         if (status == null) {
             status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
                                                        : PathStatus.INVALID;
         }
         return status == PathStatus.INVALID;
     }

It checks whether the path is valid or not. If not it throws an exception. If you are passing invalid file path, getCanonicalPath will throw an exception. Since you dont catch it and invalid is false in the beginning, it returns false

Like I said in comments, always catch Exceptions

sam
  • 2,033
  • 2
  • 10
  • 13
  • Many thanks. I should have thought of that myself. Was just too fixed that the exception should occur when the file is created (apparently believing is inferior to testing). Sometimes I am just too blind to see the obvious. However, I redebugged the whole thing again with a closer eye on where the exception turns up. Seems to be that `isValid()` is not responsible as it only tests for the final null charater at the end of the file. Appears to be the `canonicalize()` method respectively the `canonicalize0()` method (native code!?) where the actual exception is thrown. – Marco N. Oct 15 '15 at 14:35
  • @MarcoN. You're welcome. Exceptions are there for a reason so keep it a habit to always use them. – sam Oct 15 '15 at 14:38