Вопрос-ответ

Java says FileNotFoundException but file exists

Java говорит, что FileNotFoundException, но файл существует

У меня есть задание для моего класса CS, в котором говорится прочитать файл с несколькими результатами тестов и просит меня суммировать и усреднять их. Хотя суммирование и усреднение просты, у меня возникают проблемы с чтением файла. Инструктор сказал использовать этот синтаксис

Scanner scores = new Scanner(new File("scores.dat"));

Однако это выдает FileNotFoundException, но я проверял снова и снова, существует ли файл в текущей папке, и после этого я понял, что ему нужно что-то сделать с разрешениями. Я изменил разрешения на чтение и запись для всех, но это по-прежнему не сработало и продолжает выдавать ошибку. У кого-нибудь есть какие-либо идеи, почему это может происходить?

РЕДАКТИРОВАТЬ: На самом деле он указывал на каталог вверх, однако я исправил эту проблему. Теперь file.exists() возвращает true, но когда я пытаюсь поместить его в Scanner, он выдает FileNotFoundException

Вот весь мой код

import java.util.Scanner;
import java.io.*;
public class readInt{
public static void main(String args[]){
File file = new File("lines.txt");
System.out.println(file.exists());
Scanner scan = new Scanner(file);
}
}
Переведено автоматически
Ответ 1

Есть несколько ситуаций, когда FileNotFoundException может быть выдано во время выполнения.


  1. Именованный файл не существует. Это может быть по ряду причин, в том числе:



    • Путь просто неверен

    • Имя пути выглядит правильным, но на самом деле неверно, потому что оно содержит непечатаемые символы (или гомоглифы), которые вы не заметили

    • Имя пути является относительным, и оно не разрешается корректно относительно фактического текущего каталога запущенного приложения. Обычно это происходит потому, что текущий каталог приложения - это не то, что вы ожидаете или предполагаете.

    • Путь к файлу is нарушен; например, неверно указано имя каталога пути, нарушена символическая ссылка в пути или проблема с разрешением с одним из компонентов пути.



  2. Именованный файл на самом деле является каталогом.



  3. По какой-то причине указанный файл не может быть открыт для чтения.



Хорошая новость в том, что проблема неизбежно будет одной из вышеупомянутых. Это всего лишь вопрос определения того, какой именно. Вот несколько вещей, которые вы можете попробовать:


  • Вызов file.exists() сообщит вам, существует ли какой-либо объект файловой системы с заданным именем / путем.



  • Вызов file.isDirectory() проверит, является ли это каталогом.



  • Вызов file.canRead() проверит, является ли это читаемым файлом.



  • В этой строке будет указано, что это за текущий каталог:


      System.out.println(new File(".").getAbsolutePath());


  • В этой строке будет выведен путь таким образом, чтобы было легче определять такие вещи, как неожиданные начальные или завершающие пробелы:


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

    Ищите неожиданные пробелы, разрывы строк и т.д. В выходных данных.




Оказывается, в вашем примере кода произошла ошибка компиляции.

Я запустил ваш код, не обратив внимания на жалобу от Netbeans, только для того, чтобы получить следующее сообщение об исключении:


Исключение в потоке "main" java.lang.RuntimeException: некомпилируемый исходный код - незарегистрированное исключение java.io.FileNotFoundException; должно быть перехвачено или объявлено для выброса


Если вы измените свой код на следующий, это исправит эту проблему.

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

Объяснение: Scanner(File) конструктор объявлен как создающий FileNotFoundException исключение. (Случается, что сканер не может открыть файл.) Теперь FileNotFoundException это проверенное исключение. Это означает, что метод, в котором может быть выдано исключение, должен либо перехватить исключение, либо объявить его в throws предложении. Приведенное выше исправление использует последний подход.

Ответ 2

Сам код работает корректно. Проблема в том, что рабочий путь программы указывает на другое место, чем вы думаете.

Используйте эту строку и посмотрите, где находится путь:

System.out.println(new File(".").getAbsoluteFile());
Ответ 3

Оказалось, что файл не существует, хотя казалось, что он существует. Проблема заключалась в том, что Windows 7 была настроена на "Скрытие расширений файлов для известных типов файлов". Это означает, что если файл имеет имя "data.txt", то его фактическое имя файла равно "data.txt.txt".

Ответ 4

Недавно я обнаружил интересный случай, который вызывает FileNotFoundException, когда файл, очевидно, существует на диске. В моей программе я считываю путь к файлу из другого текстового файла и создаю файловый объект:

//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

Причиной проблемы было то, что путь содержал невидимые \r\n символы в конце.

Исправление в моем случае было:

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

Чтобы немного обобщить, невидимые / непечатаемые символы могли включать в себя символы пробела или табуляции и, возможно, другие, и они могли появиться в начале пути, в конце или встроены в путь. Trim будет работать в некоторых случаях, но не во всех. Есть пара вещей, которые могут помочь выявить проблему такого рода.:


  1. Выведите путь, заключив его в кавычки; например


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

    и внимательно проверьте выходные данные на наличие пробелов и переносов строк там, где их быть не должно.


  2. Используйте Java-отладчик, чтобы тщательно изучить строку имени пути, символ за символом, в поисках символов, которых там быть не должно. (Также проверьте наличие символов-гомоглифов!)


java