Java says FileNotFoundException but file exists

前端 未结 10 1372
遇见更好的自我
遇见更好的自我 2020-11-22 10:19

I have an assignment for my CS class where it says to read a file with several test scores and asks me to sum and average them. While summing and averaging is easy, I am hav

相关标签:
10条回答
  • 2020-11-22 10:29

    There are a number situation where a FileNotFoundException may be thrown at runtime.

    1. The named file does not exist. This could be for a number of reasons including:

      • The pathname is simply wrong
      • The pathname looks correct but is actually wrong because it contains non-printing characters (or homoglyphs) that you did not notice
      • The pathname is relative, and it doesn't resolve correctly relative to the actual current directory of the running application. This typically happens because the application's current directory is not what you are expecting or assuming.
      • The path to the file is is broken; e.g. a directory name of the path is incorrect, a symbolic link on the path is broken, or there is a permission problem with one of the path components.
    2. The named file is actually a directory.

    3. The named file cannot be opened for reading for some reason.

    The good news that, the problem will inevitably be one of the above. It is just a matter of working out which. Here are some things that you can try:

    • Calling file.exists() will tell you if any file system object exists with the given name / pathname.
    • Calling file.isDirectory() will test if it is a directory.
    • Calling file.canRead() will test if it is a readable file.
    • This line will tell you what the current directory is:

      System.out.println(new File(".").getAbsolutePath());
      
    • This line will print out the pathname in a way that makes it easier to spot things like unexpected leading or trainiong whitespace:

      System.out.println("The path is '" + path + "'");
      

      Look for unexpected spaces, line breaks, etc in the output.


    It turns out that your example code has a compilation error.

    I ran your code without taking care of the complaint from Netbeans, only to get the following exception message:

    Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown

    If you change your code to the following, it will fix that problem.

    public static void main(String[] args) throws FileNotFoundException {    
        File file = new File("scores.dat");
        System.out.println(file.exists());
        Scanner scan = new Scanner(file);
    }
    

    Explanation: the Scanner(File) constructor is declared as throwing the FileNotFoundException exception. (It happens the scanner it cannot open the file.) Now FileNotFoundException is a checked exception. That means that a method in which the exception may be thrown must either catch the exception or declare it in the throws clause. The above fix takes the latter approach.

    0 讨论(0)
  • 2020-11-22 10:30

    An easy fix, which worked for me, is moving my files out of src and into the main folder of the project. It's not the best solution, but depending on the magnitude of the project and your time, it might be just perfect.

    0 讨论(0)
  • 2020-11-22 10:37

    I recently found interesting case that produces FileNotFoundExeption when file is obviously exists on the disk. In my program I read file path from another text file and create File object:

    //String path was read from file
    System.out.println(path); //file with exactly same visible path exists on disk
    File file = new File(path); 
    System.out.println(file.exists());  //false
    System.out.println(file.canRead());  //false
    FileInputStream fis = new FileInputStream(file);  // FileNotFoundExeption 
    

    The cause of the problem was that the path contained invisible \r\n characters at the end.

    The fix in my case was:

    File file = new File(path.trim()); 
    

    To generalize a bit, the invisible / non-printing characters could have include space or tab characters, and possibly others, and they could have appeared at the beginning of the path, at the end, or embedded in the path. Trim will work in some cases but not all. There are a couple of things that you can help to spot this kind of problem:

    1. Output the pathname with quote characters around it; e.g.

        System.out.println("Check me! '" + path + "'");
      

      and carefully check the output for spaces and line breaks where they shouldn't be.

    2. Use a Java debugger to carefully examine the pathname string, character by character, looking for characters that shouldn't be there. (Also check for homoglyph characters!)

    0 讨论(0)
  • 2020-11-22 10:41

    Apart from all the other answers mentioned here, you can do one thing which worked for me.

    If you are reading the path through Scanner or through command line args, instead of copy pasting the path directly from Windows Explorer just manually type in the path.

    It worked for me, hope it helps someone :)

    0 讨论(0)
  • 2020-11-22 10:42

    The code itself is working correctly. The problem is, that the program working path is pointing to other place than you think.

    Use this line and see where the path is:

    System.out.println(new File(".").getAbsoluteFile());
    
    0 讨论(0)
  • 2020-11-22 10:42

    Reading and writing from and to a file can be blocked by your OS depending on the file's permission attributes.

    If you are trying to read from the file, then I recommend using File's setReadable method to set it to true, or, this code for instance:

    String arbitrary_path = "C:/Users/Username/Blah.txt";
    byte[] data_of_file;
    File f = new File(arbitrary_path);
    f.setReadable(true);
    data_of_file = Files.readAllBytes(f);
    f.setReadable(false); // do this if you want to prevent un-knowledgeable 
                          //programmers from accessing your file.
    

    If you are trying to write to the file, then I recommend using File's setWritable method to set it to true, or, this code for instance:

    String arbitrary_path = "C:/Users/Username/Blah.txt";
    byte[] data_of_file = { (byte) 0x00, (byte) 0xFF, (byte) 0xEE };
    File f = new File(arbitrary_path);
    f.setWritable(true);
    Files.write(f, byte_array);
    f.setWritable(false); // do this if you want to prevent un-knowledgeable 
                          //programmers from changing your file (for security.)
    
    0 讨论(0)
提交回复
热议问题