File.exists () повертає значення false, коли файл існує


90

Я зіткнувся з помилкою, за якою я не можу знайти жодної логіки. У мене є цей об’єкт File, який створюється так:

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

Тоді я це роблю file.exists(), і воно повертається false(!?). Якщо файл не знайдено, я реєструюсь f.getAbsolutePath()у файлі. Коли я дивлюсь на шлях, це здається ОК. Я можу скопіювати та вставити повний шлях у вікно "Виконати" у Windows, і файл відкриється нормально.

Файл існує постійно і не видаляється та не змінюється під час запуску моєї програми. Він знаходиться біля місцевої машини.

Здається, це відбувається лише у певних ситуаціях. Я можу відтворити несправність у будь-який час, але я впевнений, що шлях до файлового об'єкта не змінюється діями, які я роблю для відтворення несправності.

Що може спричинити file.exists()повернення false? Чи має це щось спільне з дозволами, блокуванням файлів тощо?


Отже, чи можна читати з файлу, навіть якщо існує () повертає 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. Якщо ці два шляхи не збігаються, ви отримуєте суперечливі результати. Диявольський!
Roman Zenka

3
У мене точно така ж проблема, я намагався використовувати обидва методи, щоб перевірити, чи існує файл, і все одно я отримую помилку лише у Windows 7! Будь-яка ідея?
Dejell

@Odelya: Яку IDE ви використовуєте? Для чого встановлений ваш -Duser.dir? Мою проблему спричинило встановлення -Duser.dir в інший каталог, ніж поточний робочий.
Роман Зенька

1
Для тих, хто працює над динамічним веб-проектом, використання file.exists () видасть виняток, використовуйте file.getAbsoluteFile (). Існує (), щоб перевірити наявність файлів у каталозі WEB-INF (загальна порада, не для Windows 7 ).
PS

Подумайте про створення окремого контролю якості для цієї відповіді та коментарів
Бато-Баїр Циренов

17

Здається, є різниця в тому, як вказаний шлях у Java.

Наприклад, якщо шлях до файлу вказаний як file:/C:/DEV/test.txtтоді

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

повернеться false. Шлях може працювати в провіднику або браузері, але це URL-адреса, а не абсолютний шлях до файлу.

Але з іншого боку, якщо шлях до файлу вказаний як C:/DEV/test.txtтоді

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

повернеться, trueоскільки шлях не є URL-адресою, але це абсолютний шлях.

З Spring Framework це саме те, що ResourceUtils.getFile(filename)робить - де ім’я може бути як URL-адресою, так і абсолютним шляхом до файлу.


5
Я не очікував file:/C:/DEV/test.txtби працювати як ім’я шляху. Це URL-адреса, а не назва шляху. Хоча деякі люди роблять цю помилку, немає жодних доказів наявності ОП ...
Стівен С

15

Якщо процес не має дозволів визначити, чи існує файл, він поверне значення false. Можливо, можливо відкрити файл, але звичайними методами не визначити, чи він існує.


20
Цікаво. Чи можете ви розширити це? Які конкретні дозволи ви маєте на увазі?
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.03.16

1
OMG, це справді працює (обидва), я просто тупо перевіряв наявність неправильного файлу і наткнувся на це запитання, щоб з'ясувати, чому жоден з них не працює для мене :) До речі, здається (), відсутні у другому рядку після exists; )
RAM237

3

Якщо встановлено прапорець ["Сховати розширення для відомих типів файлів."], Вікна відкривають "t.txt.txt", коли вводять "t.txt" у [провідник] / [запустити windows], але програмно - ні.


1
У мене виникла ця проблема, і проблема полягала в тому, що я створив txt-файл, який називався 'testFile.txt', у C: \ test. Я посилався на цей файл, використовуючи шлях C: \ test \ testFile.txt, який не працював. Це було тому, що файл насправді було збережено як testFile.txt.txt, отже, голосування за вищезазначене рішення (старе питання, але не прийнято відповіді!)
Theblacknight

Боже, Windows так сильно смокче.
aafc

3

Очевидно, що існує низка можливих причин, і попередні відповіді їх добре документують, але ось як я це вирішив в одному конкретному випадку:

У мого студента була ця проблема, і я ледь не вирвав волосся, намагаючись зрозуміти це. З’ясувалося, що файл не існує, хоча він так і виглядав. Проблема полягала в тому, що Windows 7 було налаштовано на "Сховати розширення файлів для відомих типів файлів". Це означає, що якщо файл, схоже, має ім'я "data.txt", його фактичним ім'ям є "data.txt.txt".

Сподіваюся, це допомагає іншим врятувати собі волосся.


Я не думаю, що це було питання в моєму випадку. Як уже згадувалося у моєму запитанні: "Я можу скопіювати та вставити повний шлях у вікно" Виконати "у Windows, і файл відкриється нормально.", Що означає, що файл насправді існує.
atsjoo

3

new FileКоманда просто створює екземпляр файлу , використовуючи дане ім'я шляху. Фактично це не створює файл на жорсткому диску.

Якщо ви говорите

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

Це може повернути true лише у тому випадку, якщо існував файл із однаковим шляхом. Якщо ви мали намір перевірити той самий файл, заявлений у першому рядку, можливо, вам доведеться використовувати його таким чином.

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

Тепер це повернеться правдою.


невелике пояснення: кожен виклик конструктора за допомогою нового ключового слова створює Об'єкт - такий самий, як у цьому випадку Об'єкт, описаний Класом, ім'я якого - Файл! тож не екземпляр File! = descriptors :)
ceph3us

3

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

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

Я пропоную оточити його блоком try-catch, BTW.


3

Щоб узагальнити проблему, виникає проблема під час перетворення 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();

Це очистить ваш рядок від будь-якого небажаного характеру


-1

Нещодавно я стикався з цим самим питанням. Що я зробив, це видалив Netbeans, видалив папку netbeans з диска C, програмні файли, оновлення, programData, практично скрізь. Потім переінсталюйте. Зараз працює нормально. Не забудьте створити резервну копію папки проекту netbeans, перш ніж виконувати наведені вище дії.

Сподіваюся, це допоможе.


-1

З деякими IDE (може бути) та або з деякими ОС (наприклад: вікно), за замовчуванням вони не мають доступу до файлів. Отже, якщо ви спробуєте зробити файл.exists (), він покаже вам помилку. для того, щоб це виправити, зробіть, як показано нижче

якщо вашою змінною ref для File є f, приклад: File f = new File ("шлях");

тому для того, щоб це працювало, виберіть f за допомогою миші, а потім перейдіть до меню Пошук> Доступ для запису> Робоча область. Сподіваємось, це спрацює.


-2

Я думаю, замість цього слід використовувати зворотну косу риску:

Файл файлу = новий файл ("C: \\ Користувач \\ утиліти \\ дані \\ someTextFile.txt"); (дві зворотні риски, не друкарська помилка)

Повинен вирішити проблему :)


3
Я думаю, що проблема більше пов’язана з абсолютним шляхом та відносним шляхом. Коса риса дійсна в Java навіть для шляхів Windows.
рюффп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.