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
может быть выдано во время выполнения.
Именованный файл не существует. Это может быть по ряду причин, в том числе:
- Путь просто неверен
- Имя пути выглядит правильным, но на самом деле неверно, потому что оно содержит непечатаемые символы (или гомоглифы), которые вы не заметили
- Имя пути является относительным, и оно не разрешается корректно относительно фактического текущего каталога запущенного приложения. Обычно это происходит потому, что текущий каталог приложения - это не то, что вы ожидаете или предполагаете.
- Путь к файлу is нарушен; например, неверно указано имя каталога пути, нарушена символическая ссылка в пути или проблема с разрешением с одним из компонентов пути.
Именованный файл на самом деле является каталогом.
По какой-то причине указанный файл не может быть открыт для чтения.
Хорошая новость в том, что проблема неизбежно будет одной из вышеупомянутых. Это всего лишь вопрос определения того, какой именно. Вот несколько вещей, которые вы можете попробовать:
Вызов
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 будет работать в некоторых случаях, но не во всех. Есть пара вещей, которые могут помочь выявить проблему такого рода.:
Выведите путь, заключив его в кавычки; например
System.out.println("Check me! '" + path + "'");
и внимательно проверьте выходные данные на наличие пробелов и переносов строк там, где их быть не должно.
Используйте Java-отладчик, чтобы тщательно изучить строку имени пути, символ за символом, в поисках символов, которых там быть не должно. (Также проверьте наличие символов-гомоглифов!)