File.exists () возвращает false, если файл существует

91

Я столкнулся с ошибкой, в которой не могу найти никакой логики. У меня есть этот объект File, который создается следующим образом:

File file = new File("utilities/data/someTextFile.txt");

Я тогда делаю file.exists(), и он возвращается false(!?). Если файл не найден, я вхожу f.getAbsolutePath()в файл. Когда я смотрю на тропинку, все в порядке. Я могу скопировать и вставить полный путь в окно «Выполнить» в Windows, и файл откроется нормально.

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

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

Что может привести file.exists()к возврату false? Связано ли это с разрешениями или блокировками файлов и т. Д.?

Atsjoo
источник
Итак, можно ли читать из файла, даже если exists () возвращает false?
Гарри Лайм
да, я могу читать из файла, даже если существует () возвращает false.
atsjoo
1
Что именно нужно для воспроизведения неисправности?
user85421
1
Это внутри приложения, которое вызывает функции, написанные в Matlab и скомпилированные в приложение java. Похоже, что функции Matlab, которые изменяют «текущий каталог», вызывают проблему. Я использую абсолютный путь при создании файлового объекта, так что это не должно быть проблемой - как бы то ни было. Я, конечно, проверил абсолютный путь к объекту файла, и он правильный (так же, как это было до того, как функция matlab изменила текущий каталог).
atsjoo
7
Вы случайно не работаете с удаленным каталогом (например, с монтированием NFS)?
Томер Гэбл

Ответы:

42

В Windows 7 я вижу следующую ситуацию:

file.exists() == false
file.getAbsoluteFile().exists() == true

Рассматриваемый файл - "var \ log", абсолютный путь действительно относится к существующему файлу, который находится в обычном подкаталоге (не в виртуальном хранилище). Это видно из IDE.

Роман Зенка
источник
17
Я только что понял: bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097 По-видимому, операции, выполняемые с файлом, разрешаются относительно текущего каталога, а getAbsolutePath разрешает против user.dir. Если эти два пути не совпадают, вы получите противоречивые результаты. Дьявольски!
Роман Зенка
3
У меня точно такая же проблема, как я пытался использовать оба метода, чтобы проверить, существует ли файл, и все же я получаю false только в Windows 7! Есть идеи?
Dejell
@Odelya: Какую IDE вы используете? На что установлен ваш -Duser.dir? Моя проблема была вызвана установкой -Duser.dir в каталог, отличный от текущего рабочего.
Роман Зенка,
1
Для всех, кто работает над динамическим веб-проектом, использование file.exists () вызовет исключение, используйте file.getAbsoluteFile (). Exists () для проверки файлов в каталоге WEB-INF (общий совет, а не для Windows 7 ).
PS
Рассмотрите возможность создания отдельного QA для этого ответа и комментариев
Бато-Баир Цыренов
17

Похоже, что есть разница в том, как путь указывается в Java.

Например, если путь к файлу указан как file:/C:/DEV/test.txtто

File f = new File(filename);
f.exists();

вернется false. Путь может работать в проводнике или браузере, но это URL-адрес, а не абсолютный путь к файлу.

Но с другой стороны, если путь к файлу указан как C:/DEV/test.txtthen

File f = new File(filename);
f.exists();

вернется, trueпотому что путь не является URL-адресом, но является абсолютным путем.

В Spring Framework это именно то, что ResourceUtils.getFile(filename)делает - где имя может быть либо URL-адресом, либо абсолютным путем к файлу.

Гарима Батла
источник
5
Я бы не ожидал, что буду file:/C:/DEV/test.txtработать как путь. Это URL-адрес, а не путь. Хотя некоторые люди совершают эту ошибку, нет никаких доказательств того, что ОП имеет ...
Стивен С.
15

Если у процесса нет разрешений на определение существования файла, он вернет false. Возможно, файл можно открыть, но обычными методами нельзя сказать, существует ли он.

Том Хотин - tackline
источник
21
Интересно. Можете ли вы подробнее рассказать об этом? Какие конкретные разрешения вы имеете в виду?
Clément
Здесь может быть возможность java.nio.file.AccessDeniedException, блокирующая возможность доступа к существованию файла / каталога. Например, если вы держите каталог открытым в FAR или другом проводнике файлов, затем удалите каталог со всеми вложенными файлами и проверьте наличие этого каталога, тогда вы можете получить AccessDeniedException (расширяет IOException) для временного файла, который хранится для вас. В этом случае Files.exists возвращает false для исключения IOException.
beluha
11

Приведенные выше ответы не помогли в моем случае. Как было сказано выше, у меня было:

file.exists() => false
file.getAbsoluteFile().exists => true

Основная причина этого заключалась в том, что владелец компьютера с Windows 7 изменил реестр для CMD, чтобы он автоматически запускал команду для запуска в определенном каталоге для работы с Python. Эта модификация привела к повреждению кода Java 1.6, который явно использует CMD в Windows для определенных файловых операций, таких как exists(). Устранение автозапуска из реестра решило проблему.

Карл Лью
источник
1
Спустя 3,5 года я столкнулся с той же проблемой. У меня был сценарий автозапуска, настроенный для настройки переменных среды каждый раз, когда я запускал cmd.com. Он даже не изменил текущий каталог - только несколько макросов doskey и некоторые переменные среды. Я удалил автозапуск и просто вручную запустил команды в файле, и вдруг File.exists () работает правильно.
Homr Zodyssey 01
1
OMG, это действительно работает (они оба), я просто тупо проверял не тот файл и наткнулся на этот вопрос, чтобы узнать, почему ни один из них не работает для меня :) Кстати, похоже, что ()во второй строке после exists; )
RAM237 05
3

Когда установлен флажок [«Скрывать расширения для известных типов файлов.»], Окна открывают «t.txt.txt» при вводе «t.txt» в [проводнике] / [запускать окна], но программно нет.

я тоже
источник
1
У меня была эта проблема, и проблема заключалась в том, что я создал текстовый файл, который назывался testFile.txt, в C: \ test. Я обратился к этому файлу, используя путь C: \ test \ testFile.txt, который не сработал. Это произошло потому, что файл был фактически сохранен как testFile.txt.txt, отсюда и голосование за вышеупомянутое решение (старый вопрос, но нет принятого ответа!)
Theblacknight
Бог Windows - отстой.
aafc
3

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

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

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

Petehern
источник
Я не думаю, что это было проблемой в моем случае. Как упоминалось в моем вопросе: «Я могу скопировать и вставить полный путь в окно« Выполнить »в Windows, и файл откроется нормально.», Что означает, что файл действительно существует.
atsjoo
3

Команда new Fileпросто создает экземпляр файла, используя заданное имя пути. На самом деле он не создает файл на жестком диске.

Если вы скажете

File file = new File ("path");
file.exists() 

Это может вернуть истину, только если существовал файл с таким же путем. Если вы намеревались проверить тот же файл, объявленный в первой строке, вам может потребоваться использовать его таким образом.

File file = new File ("path");
file.createNewFile();
file.exists();

Теперь это вернет истину.

R1234
источник
небольшое объяснение: каждый вызов конструктора с использованием ключевого слова new создает объект - такой же, как в этом случае, объект, описанный классом, имя которого - File! так что не экземпляр File! = дескрипторов :)
ceph3us
3

Если вы не хотите иметь дело с вызовами getAbsoluteFile () каждый раз, когда вам нужно вызвать метод, вам лучше создать экземпляр файла с абсолютным путем. Это должно помочь:

File file = new File("utilities/data/someTextFile.txt").getAbsoluteFile();

Я предлагаю окружить его блоком try-catch, BTW.

Fran Marzoa
источник
2

Чтобы обобщить проблему, проблема возникает при преобразовании URL / URI в локальные пути.

Example: URL url = file:/D:/code%20repo%20sample/sample.txt

// To remove url reference
String localPath = url.getPath();  
> /D:/code%20repo%20sample/sample.txt

// Decoding reserved characters in url from hexadecimal to character
URLDecoder.decode(localPath, StandardCharsets.UTF_8.toString()); 
> /D:/code repo sample/sample.txt

Надеюсь это поможет.

Арун
источник
0

Всем хорошие отзывы. Я обнаружил, что это проблема с доступом Java к корневому C:каталогу в Windows. Любой другой каталог должен быть хорошо, но по какой - то причине, в частности , упомянуть C:\или C:или C:/может дать ошибку. Я решил эту очень похожую проблему, перехватив упоминание new File("C:");и заменив его новым, File(System.getProperty("file.separator"));иначе вы сможете жестко закодировать «\» вместо «c:» в качестве каталога с файлами, и это может сработать. Не изящно, но выполнил работу за меня в этом проекте.

Я надеюсь, что это помогает. Возможно, это неправильное решение, но, по крайней мере, оно сработало для меня. Я иду JRE 1.6, Win 7. Ура!

С уважением,

@ Carpenter1010

Код Карпентер
источник
0

Если в ситуациях, когда он терпит неудачу, запускается его от имени другого пользователя, и вы используете Windows Vista / Windows 7, это может быть вызвано VirtualStore, механизмом, при котором Windows позволяет непривилегированному пользователю «писать», чего он обычно не может. Однако изменения хранятся в "% USERPROFILE% \ AppData \ Local \ VirtualStore \", который является частным для каждой учетной записи пользователя.

Кьетил Йоргенсен
источник
1
Я работаю на windows xp x86
atsjoo
0

Когда у меня ничего сверху не работало, я попробовал

filePath = filePath.trim();

Это очистит вашу строку от любых нежелательных символов.

Асим
источник
0

FWIW, есть еще одно место, где это происходит.

File("")это имя текущего каталога. File("").exists()обычно вернусь false. File(("").getAbsoluteFile().exists()Трюк работает и будет возвращать true(предполагая , текущий каталог существует ...)

Г. Блейк Мейке
источник
-1

Недавно я столкнулся с этой же проблемой. Я удалил Netbeans, удалил папку netbeans с диска C, программные файлы, update, programData практически везде. Затем переустановите. Сейчас работает нормально. Не забудьте сделать резервную копию папки проекта netbeans, прежде чем предпринимать действия, указанные выше.

Надеюсь, поможет.

Evaboy
источник
-1

С некоторой IDE (может быть) и / или с некоторой ОС (например: window) по умолчанию у них нет доступа на запись в файлы. Поэтому, если вы попытаетесь выполнить file.exists (), он покажет вам false. чтобы исправить это, сделайте как показано ниже

если ваша переменная ref для File - f, например: File f = new File ("path");

поэтому, чтобы заставить его работать, выберите f мышью и затем перейдите в меню «Поиск»> «Доступ для записи»> «Рабочая область». Надеюсь, это сработает.

Гаутам Ананд
источник
-2

Я думаю, вам следует использовать обратную косую черту, например:

Файл file = новый файл ("C: \\ User \\ utilities \\ data \\ someTextFile.txt"); (две обратные косые черты, а не опечатка)

Должно решить проблему :)

Хусейн Мазиад
источник
3
Я думаю, что проблема больше связана с абсолютным путем против относительного пути. Косая черта действительна в Java даже для путей Windows.
рüффп