File.exists () mengembalikan nilai salah jika file ada

90

Saya mengalami bug yang sepertinya tidak dapat saya temukan logika apa pun di baliknya. Saya memiliki objek File ini, yang dibuat seperti ini:

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

Saya kemudian melakukannya file.exists(), dan kembali false(!?). Jika file tidak ditemukan, saya masuk f.getAbsolutePath()ke file. Ketika saya melihat jalannya, sepertinya OK. Saya dapat menyalin-tempel jalur lengkap ke dalam jendela "Jalankan" di Windows dan file terbuka dengan baik.

File tersebut ada setiap saat dan tidak dihapus atau diubah selama menjalankan aplikasi saya. Itu terletak di mesin lokal.

Ini sepertinya hanya terjadi dalam situasi tertentu. Saya dapat mereproduksi kesalahan kapan saja, tetapi saya yakin jalur objek file tidak diubah oleh tindakan yang saya buat untuk mereproduksi kesalahan.

Apa yang bisa menyebabkan file.exists()return false? Apakah ini ada hubungannya dengan izin atau kunci file, dll.?

atsjoo
sumber
Jadi, apakah mungkin untuk membaca dari file bahkan jika ada () mengembalikan false?
Harry Lime
ya, saya bisa membaca dari file tersebut bahkan jika ada () mengembalikan salah.
atsjoo
1
Apa sebenarnya yang dibutuhkan untuk mereproduksi kesalahan?
pengguna85421
1
Ini ada di dalam aplikasi yang memanggil fungsi-fungsi yang ditulis dalam matlab dan dikompilasi ke dalam aplikasi java. Sepertinya fungsi matlab yang mengubah "direktori saat ini" menyebabkan masalah muncul. Saya menggunakan jalur absolut saat membuat objek file, jadi ini seharusnya tidak menjadi masalah - bagaimanapun tampaknya. Saya tentu saja telah memverifikasi jalur absolut dari objek file, dan itu benar (sama seperti sebelum fungsi matlab mengubah direktori saat ini).
atsjoo
7
Apakah Anda kebetulan bekerja pada direktori jarak jauh (misalnya mount NFS)?
Tomer Gabel

Jawaban:

42

Saya melihat situasi berikut di Windows 7:

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

File yang dimaksud adalah "var \ log", path absolut mengacu pada file yang ada di subdirektori normal (bukan toko virtual). Ini terlihat dari IDE.

Roman Zenka
sumber
17
Saya baru saja mengetahuinya: bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097 Rupanya, operasi yang berjalan pada file diselesaikan terhadap direktori saat ini, sementara getAbsolutePath menyelesaikannya terhadap user.dir. Jika kedua jalur ini tidak cocok, Anda mendapatkan hasil yang bertentangan. Jahat!
Roman Zenka
3
Saya memiliki masalah yang sama persis. Saya mencoba menggunakan kedua metode untuk memeriksa apakah file ada, dan saya tetap salah hanya pada Windows 7! Ada ide?
Dejell
@Odelya: IDE apa yang Anda gunakan? Apa set -Duser.dir Anda? Masalah saya disebabkan oleh pengaturan -Duser.dir ke direktori yang berbeda dari yang berfungsi saat ini.
Roman Zenka
1
Bagi siapa pun yang mengerjakan Proyek Web Dinamis, menggunakan file.exists () akan membuat pengecualian, gunakan file.getAbsoluteFile (). Existing () untuk memeriksa file di direktori WEB-INF (tip umum, bukan khusus Windows 7 ).
PS
Pertimbangkan untuk membuat QA terpisah untuk jawaban dan komentar ini
Bato-Bair Tsyrenov
17

Sepertinya ada perbedaan tentang bagaimana jalur ditentukan di Java.

Misalnya, jika jalur file ditentukan seperti file:/C:/DEV/test.txtitu

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

akan kembali false. Jalur tersebut mungkin berfungsi di penjelajah atau di browser, tetapi ini adalah URL dan bukan jalur file absolut.

Tapi di sisi lain jika path file ditentukan seperti C:/DEV/test.txtitu

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

akan kembali truekarena jalur tersebut bukan URL, tetapi jalur absolut.

Dengan Spring Framework itulah tepatnya ResourceUtils.getFile(filename)- di mana nama bisa berupa URL atau jalur file absolut.

Garima Bathla
sumber
5
Saya tidak berharap file:/C:/DEV/test.txtuntuk bekerja sebagai nama jalan. Ini adalah URL, bukan nama jalur. Sementara beberapa orang membuat kesalahan ini, tidak ada bukti bahwa OP memiliki ...
Stephen C
15

Jika proses tidak memiliki izin untuk mengetahui apakah ada file itu akan mengembalikan false. Dimungkinkan untuk membuka file, tetapi tidak diberi tahu dengan metode normal jika ada.

Tom Hawtin - tackline
sumber
20
Menarik. Dapatkah Anda memperluas ini? Izin khusus apa yang Anda pikirkan?
Clément
Berikut adalah kemampuan pemblokiran java.nio.file.AccessDeniedException untuk menjangkau keberadaan file / dir. Misalnya, jika Anda tetap membuka direktori di FAR atau file explorer lainnya, lalu hapus direktori dengan semua file bersarang dan periksa keberadaan direktori ini, maka Anda bisa mendapatkan AccessDeniedException (extends IOException) untuk file sementara yang disimpan untuk Anda. Dalam hal ini Files.exists mengembalikan false untuk IOException.
beluha
11

Jawaban di atas tidak membantu dalam kasus saya. Seperti yang dinyatakan di atas, saya memiliki:

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

Akar penyebabnya adalah pemilik mesin Windows 7 telah memodifikasi registri untuk CMD sehingga akan menjalankan perintah secara otomatis untuk diluncurkan di direktori tertentu untuk bekerja dengan Python. Modifikasi ini melumpuhkan kode Java 1.6 yang tampaknya menggunakan CMD pada Windows untuk operasi file tertentu, seperti exists(). Menghilangkan autorun dari registri memecahkan masalah.

Karl Lew
sumber
1
3,5 tahun kemudian, dan saya mengalami masalah yang sama. Saya memiliki skrip autorun yang disiapkan untuk mengonfigurasi variabel lingkungan setiap kali saya meluncurkan cmd.com. Itu bahkan tidak mengubah direktori saat ini - hanya beberapa makro doskey dan beberapa variabel lingkungan. Saya menghapus autorun, dan hanya menjalankan perintah di file secara manual, dan tiba-tiba File.exists () berfungsi dengan benar.
Homr Zodyssey
1
Ya ampun, ini benar-benar berfungsi (keduanya), saya hanya dengan bodohnya memeriksa file yang salah dan menemukan pertanyaan ini untuk mencari tahu mengapa tidak ada yang berhasil untuk saya :) BTW, tampaknya ()ada yang hilang di baris kedua setelah exists; )
RAM237
3

Ketika ["Sembunyikan ekstensi untuk jenis file yang dikenal."] Dicentang, jendela terbuka "t.txt.txt" ketika ketik "t.txt" di [explorer] / [jalankan windows] tetapi secara terprogram tidak.

saya juga
sumber
1
Saya mengalami masalah ini, dan masalahnya adalah saya membuat file txt, yang disebut 'testFile.txt', di C: \ test. Saya merujuk ke file ini menggunakan jalur C: \ test \ testFile.txt, yang tidak berfungsi. Itu karena file sebenarnya telah disimpan sebagai testFile.txt.txt, oleh karena itu suara naik pada solusi di atas (Pertanyaan lama, tetapi tidak ada jawaban yang diterima!)
Theblacknight
God Windows sangat menyebalkan.
aafc
3

Jelas ada sejumlah kemungkinan penyebab dan jawaban sebelumnya mendokumentasikannya dengan baik, tetapi inilah cara saya menyelesaikannya dalam satu kasus tertentu:

Seorang murid saya memiliki masalah ini dan saya hampir merobek rambut saya mencoba mencari tahu. Ternyata file tersebut tidak ada, meskipun sepertinya ada. Masalahnya adalah Windows 7 dikonfigurasi untuk "Sembunyikan ekstensi file untuk jenis file yang dikenal." Ini berarti bahwa jika file tampaknya memiliki nama "data.txt", nama file sebenarnya adalah "data.txt.txt".

Semoga ini bisa membantu orang lain menyelamatkan diri.

petehern
sumber
Saya tidak berpikir ini adalah masalah dalam kasus saya. Seperti yang disebutkan dalam pertanyaan saya: "Saya dapat menyalin-tempel jalur lengkap ke" Jalankan "-jendela di Windows dan file terbuka dengan baik.", Yang berarti file tersebut benar-benar ada.
atsjoo
3

Itu new File perintah hanya menciptakan sebuah instance dari file menggunakan nama path yang diberikan. Itu sebenarnya tidak membuat file di hard drive.

Jika Anda mengatakan

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

Ini dapat mengembalikan true hanya jika ada file yang sudah ada dengan jalur yang sama. Jika Anda bermaksud memeriksa file yang sama yang dideklarasikan di baris pertama, Anda mungkin perlu menggunakannya dengan cara ini.

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

Sekarang ini akan kembali menjadi kenyataan.

R1234
sumber
Penjelasan kecil: setiap panggilan ke konstruktor dengan menggunakan kata kunci baru membuat Objek - sama seperti dalam kasus ini Objek dijelaskan oleh Kelas yang namanya File! jadi bukan contoh dari File! = deskriptor :)
ceph3us
3

Jika Anda tidak ingin berurusan dengan panggilan getAbsoluteFile () setiap kali Anda harus memanggil metode, lebih baik Anda membuat instance file Anda dengan jalur absolut. Ini harus melakukan trik:

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

Saya sarankan untuk mengelilinginya dengan blok coba-tangkap, BTW.

Fran Marzoa
sumber
3

Untuk menggeneralisasi masalah, masalah muncul saat mengonversi URL / URI ke jalur lokal.

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

Semoga ini membantu.

Arun
sumber
0

Tanggapan yang baik semuanya. Saya telah menemukan ini tampaknya menjadi masalah dengan Java yang mengakses C:direktori root di Windows. Direktori lain seharusnya baik-baik saja, tetapi karena alasan tertentu, secara khusus menyebutkan C:\atau C:atau C:/mungkin memberikan kesalahan. Saya telah menyelesaikan masalah yang sangat mirip ini dengan menjebak mention ke new File("C:");dan menggantinya dengan yang baru File(System.getProperty("file.separator"));atau Anda harus dapat membuat kode keras "\" daripada mengatakan "c:" sebagai direktori file Anda dan mungkin berhasil. Tidak elegan, tetapi menyelesaikan pekerjaan untuk saya di proyek ini.

Saya harap ini membantu. Mungkin bukan solusi yang tepat, tetapi setidaknya ini berhasil untuk saya. Saya aktif JRE 1.6, Win 7. Bersulang!

Dengan hormat,

@Tukang kayu

Code Carpenter
sumber
0

Jika situasi di mana gagal melibatkan menjalankannya sebagai pengguna lain, dan Anda menggunakan Windows Vista / Windows 7, itu bisa disebabkan oleh VirtualStore, mekanisme di mana Windows membiarkan pengguna yang tidak berhak "menulis" tempat yang biasanya tidak bisa. Namun perubahan tersebut disimpan di "% USERPROFILE% \ AppData \ Local \ VirtualStore \" yang bersifat pribadi untuk setiap akun pengguna.

Kjetil Joergensen
sumber
1
Saya menjalankan windows xp x86
atsjoo
0

Ketika tidak ada dari atas yang berhasil untuk saya, saya mencoba

filePath = filePath.trim();

Ini akan membersihkan string Anda dari karakter yang tidak diinginkan

Asim
sumber
-1

Saya baru-baru ini menemukan masalah yang sama. Apa yang saya lakukan adalah menghapus instalan Netbeans, menghapus folder netbeans dari drive C, file program, pembaruan, programData, hampir di mana saja. Kemudian instal ulang. Sekarang bekerja dengan baik. Jangan lupa untuk membuat cadangan folder proyek netbeans sebelum mengambil tindakan di atas.

Semoga membantu.

Evaboy
sumber
-1

Dengan beberapa IDE (mungkin) dan atau dengan beberapa OS (mis .: window), secara default mereka tidak memiliki akses tulis pada file. Jadi jika Anda mencoba melakukan file.exists () itu akan menunjukkan Anda salah. untuk memperbaikinya, lakukan seperti di bawah ini

jika variabel ref Anda untuk File adalah f, contoh: File f = new File ("path");

jadi untuk membuatnya bekerja, pilih f dengan mouse dan kemudian pergi ke menu Search> Write access> Workspace. Semoga berhasil.

Gautam Anand
sumber
-2

Saya pikir Anda harus menggunakan garis miring terbalik, seperti ini:

File file = File baru ("C: \\ User \\ utilities \\ data \\ someTextFile.txt"); (dua garis miring terbalik, bukan salah ketik)

Harus menyelesaikan masalah :)

Hussein Maziad
sumber
3
Saya pikir masalahnya lebih terkait dengan jalur absolut vs jalur relatif. Garis miring valid di Java bahkan untuk jalur Windows.
рüффп