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);
        }
}

person scrblnrd3    schedule 10.10.2013    source источник
comment
Что такое текущий каталог? Попробуйте распечатать new File(".")   -  person Steinar    schedule 11.10.2013
comment
Выведите путь к new File("scores.dat") и дважды проверьте, существует ли он в ожидаемом каталоге.   -  person Josh M    schedule 11.10.2013
comment
@Steinar ищет в правильном каталоге и дает правильный абсолютный путь, однако файл все еще не найден   -  person scrblnrd3    schedule 11.10.2013
comment
Это на машине Unix? Если да, опубликуйте вывод ls -la из каталога, в котором вы запускаете java.   -  person chrylis -cautiouslyoptimistic-    schedule 11.10.2013
comment
Еще кое-что, что стоит попробовать: что возвращает new File("scores.dat").exists()? Что возвращает new File(".").listFiles()? Вы нашли свой файл в списке? Если вы выберете этот экземпляр, он будет работать со сканером?   -  person Steinar    schedule 11.10.2013
comment
Каков текст исключения?   -  person user207421    schedule 11.10.2013
comment
Почти наверняка вы находитесь не в том каталоге. Распечатайте new File("scores.dat").getAbsolutePath() и убедитесь, что файл действительно находится в этом месте.   -  person Hot Licks    schedule 11.10.2013
comment
просто в качестве примечания, я получал эту ошибку, вызывая new File().getName() вместо new File().getAbsolutePath(), хотя getName() вернул правильный путь, он не включал file: в начале строки.   -  person Csa77    schedule 29.08.2019


Ответы (11)


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

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

    • The pathname is simply wrong
    • Путь выглядит правильным, но на самом деле неверным, потому что он содержит непечатаемые символы (или гомоглифы), которые вы не заметили.
    • Путь является относительным и не разрешается правильно относительно фактического текущего каталога запущенного приложения. Обычно это происходит потому, что текущий каталог приложения не соответствует вашим ожиданиям или предположениям.
    • Путь к файлу нарушен; например имя каталога пути неверно, символическая ссылка на пути не работает или существует проблема с правами доступа для одного из компонентов пути.
  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. В приведенном выше исправлении используется второй подход.

person Terry Li    schedule 11.10.2013
comment
Ваш третий случай включает в себя два других, а также включает ряд других легко разделимых случаев, таких как проблемы с разрешениями, сбои сети и т. Д., Что не очень поучительно и не дает никаких оснований для того, чтобы они существовали. три случая ». Тестирование File.canRead() бесполезно, когда вам уже нужно перехватить исключение, и расточительно, когда системе все равно приходится тестировать его во время открытия. - person user207421; 27.04.2015
comment
Если приведенный выше тест вернет истину - а что, если это вернет ложь? :) - person Line; 21.02.2018

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

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

System.out.println(new File(".").getAbsoluteFile());
person libik    schedule 10.10.2013

Очевидно, существует ряд возможных причин, и предыдущие ответы хорошо документировали их, но вот как я решил это в одном конкретном случае:

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

Надеюсь, это поможет другим сберечь себе волосы.

person petehern    schedule 08.05.2015

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

//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()); 

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

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

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

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

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

person yurin    schedule 11.08.2016

Чтение и запись из файла и в файл могут быть заблокированы вашей ОС в зависимости от атрибутов разрешений файла.

Если вы пытаетесь читать из файла, я рекомендую использовать метод File setReadable, чтобы установить для него значение true, или, например, этот код:

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.

Если вы пытаетесь записать в файл, я рекомендую использовать метод File setWritable, чтобы установить для него значение true, или, например, этот код:

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.)
person Solumyr    schedule 07.07.2017

Простое исправление, которое сработало для меня, - переместить мои файлы из src в основную папку проекта. Это не лучшее решение, но в зависимости от масштабов проекта и вашего времени оно может быть просто идеальным.

person Irina Larisa    schedule 21.10.2018

Помимо всех других ответов, упомянутых здесь, вы можете сделать одну вещь, которая сработала для меня.

Если вы читаете путь через сканер или через аргументы командной строки, вместо копирования и вставки пути непосредственно из проводника Windows просто введите путь вручную.

У меня это сработало, надеюсь, это кому-то поможет :)

person Alok    schedule 27.05.2017

У меня была такая же ошибка, и я решил ее, просто добавив каталог src, который находится в структуре проекта Java.

String path = System.getProperty("user.dir") + "\\src\\package_name\\file_name";
File file = new File(path);
Scanner scanner = new Scanner(file);

Обратите внимание, что System.getProperty ("user.dir") и новый файл ("."). GetAbsolutePath () возвращают путь к корневому каталогу вашего проекта, поэтому вам нужно добавить путь к своим подкаталогам и пакетам

person lewiscool    schedule 11.05.2019
comment
Хотя это сработало для вас, у этого подхода есть проблемы. 1) Вы делаете платформу своего приложения зависимой с помощью синтаксиса пути, специфичного для Windows. 2) Вы предполагаете, что ваш код будет выполняться с текущим каталогом, установленным в каталог сборки (или что-то еще). Это не сработает, если вы отправите код кому-то другому. - person Stephen C; 03.08.2019
comment
Если файл, который вы пытаетесь прочитать, является частью базы исходного кода, лучше скопировать его в файл JAR (или в дерево файлов, содержащее ваши скомпилированные классы) и использовать getResourceAsStream, чтобы найти его через путь к классам (времени выполнения). - person Stephen C; 03.08.2019

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

person Aditya Vikas Devarapalli    schedule 03.01.2020

Используйте одинарную косую черту и всегда вводите путь вручную. Например:

FileInputStream fi= new FileInputStream("D:/excelfiles/myxcel.xlsx");
person Lefin K.R    schedule 21.02.2020

Что сработало для меня, так это перехват исключения. Без этого компилятор жалуется, даже если файл существует.

InputStream file = new FileInputStream("filename");

изменился на

try{
    InputStream file = new FileInputStream("filename");
    System.out.println(file.available());
}
catch (Exception e){
    System.out.println(e);
}
person tejasvi88    schedule 08.03.2021