File.exists () restituisce false quando il file esiste


90

Ho riscontrato un bug che non riesco a trovare alcuna logica dietro. Ho questo oggetto File, che viene creato in questo modo:

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

Allora lo faccio file.exists()e ritorna false(!?). Se il file non viene trovato, accedo f.getAbsolutePath()a un file. Quando guardo il percorso, sembra OK. Posso copiare e incollare il percorso completo nella finestra "Esegui" in Windows e il file si apre correttamente.

Il file esiste sempre e non viene cancellato né modificato durante l'esecuzione della mia applicazione. Si trova nella macchina locale.

Questo sembra accadere solo in determinate situazioni. Posso riprodurre l'errore in qualsiasi momento, ma sono sicuro che il percorso dell'oggetto file non viene modificato dalle azioni che faccio per riprodurre l'errore.

Cosa può causare la file.exists()restituzione di false? Ha qualcosa a che fare con i permessi, i blocchi dei file, ecc.


Quindi, è possibile leggere dal file anche se exist () restituisce false?
Harry Lime,

sì, posso leggere dal file anche se exist () restituisce false.
atsjoo

1
Cosa è necessario esattamente per riprodurre l'errore?
user85421

1
Questo è all'interno di un'applicazione che chiama funzioni scritte in matlab e compilate nell'applicazione java. Sembra che le funzioni matlab che cambiano la "directory corrente" stiano causando la comparsa del problema. Sto usando il percorso assoluto durante la creazione dell'oggetto file, quindi questo non dovrebbe essere un problema, comunque sembri. Ovviamente ho verificato il percorso assoluto dell'oggetto file ed è corretto (lo stesso di prima che la funzione matlab cambiasse la directory corrente).
atsjoo

7
Stai per caso lavorando su una directory remota (ad esempio un montaggio NFS)?
Tomer Gabel

Risposte:


42

Vedo la seguente situazione su Windows 7:

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

Il file in questione è "var \ log", il percorso assoluto fa riferimento a un file esistente che si trova in una normale sottodirectory (non un archivio virtuale). Questo è visto dall'IDE.


16
L'ho appena capito: bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097 Apparentemente, le operazioni in esecuzione su file vengono risolte nella directory corrente, mentre getAbsolutePath si risolve in user.dir. Se questi due percorsi non corrispondono, si ottengono risultati contrastanti. Diabolico!
Roman Zenka

3
Ho lo stesso identico problema Ho provato a utilizzare entrambi i metodi per verificare se il file esiste, e ancora ottengo false solo su Windows 7! Qualche idea?
Dejell

@ Odelya: quale IDE stai usando? Su cosa è impostato il tuo -Duser.dir? Il mio problema è stato causato dall'impostazione di -Duser.dir su una directory diversa da quella di lavoro corrente.
Roman Zenka

1
Per chiunque stia lavorando a un progetto Web dinamico, l'utilizzo di file.exists () genererà un'eccezione, utilizzare file.getAbsoluteFile (). Exist () per verificare la presenza di file nella directory WEB-INF (suggerimento generale, non specifico di Windows 7 ).
PS

Considera la possibilità di creare un QA separato per questa risposta e commenti
Bato-Bair Tsyrenov

17

Sembra che ci sia una differenza nel modo in cui il percorso viene specificato in Java.

Ad esempio, se il percorso del file è specificato come file:/C:/DEV/test.txtallora

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

tornerà false. Il percorso potrebbe funzionare nell'explorer o nel browser, ma è un URL e non un percorso di file assoluto.

Ma d'altra parte se il percorso del file è specificato come C:/DEV/test.txtallora

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

restituirà trueperché il percorso non è un URL, ma è un percorso assoluto.

Con Spring Framework questo è esattamente ciò che ResourceUtils.getFile(filename)fa - dove il nome può essere un URL o il percorso del file assoluto.


5
Non mi aspetto file:/C:/DEV/test.txtdi lavorare come nome di percorso. È un URL, non un percorso. Sebbene alcune persone commettano questo errore, non ci sono prove che l'OP abbia ...
Stephen C

15

Se il processo non dispone delle autorizzazioni per indicare se un file esiste, restituirà false. Potrebbe essere possibile aprire un file, ma non dire con metodi normali se esiste.


20
Interessante. Puoi approfondire su questo? Quali autorizzazioni specifiche hai in mente?
Clément

Qui può essere java.nio.file.AccessDeniedException che blocca la capacità di raggiungere l'esistenza di file / directory. Ad esempio, se mantieni la directory aperta in FAR o un altro file explorer, quindi elimini la directory con tutti i file nidificati e controlli l'esistenza di questa directory, puoi ottenere AccessDeniedException (estende IOException) per il file temporaneo conservato per te. In questo caso Files.exists restituisce false per IOException.
beluha

11

Le risposte di cui sopra non hanno aiutato nel mio caso. Come detto sopra, ho avuto:

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

La causa principale di ciò era che il proprietario della macchina Windows 7 aveva modificato il registro per CMD in modo che eseguisse automaticamente un comando da avviare in una directory specifica per lavorare con Python. Questa modifica ha paralizzato il codice Java 1.6 che apparentemente utilizza CMD su Windows per alcune operazioni sui file, come exists(). L'eliminazione dell'esecuzione automatica dal registro ha risolto il problema.


1
3,5 anni dopo, e mi sono imbattuto nello stesso problema. Avevo impostato uno script di esecuzione automatica per configurare le variabili di ambiente ogni volta che avviavo cmd.com. Non ha nemmeno cambiato la directory corrente - solo alcune macro doskey e alcune variabili d'ambiente. Ho rimosso l'esecuzione automatica e ho eseguito manualmente i comandi nel file e improvvisamente File.exists () funziona correttamente.
Homr Zodyssey

1
OMG, funziona davvero (entrambi), stavo solo controllando stupidamente il file sbagliato e mi sono imbattuto in questa domanda per scoprire perché nessuno di loro funziona per me :) BTW, sembra che ()manchino nella seconda riga dopo exists; )
RAM237

3

Ovviamente ci sono una serie di possibili cause e le risposte precedenti le documentano bene, ma ecco come l'ho risolto in un caso particolare:

Un mio studente ha avuto questo problema e mi sono quasi strappato i capelli cercando di capirlo. Si è scoperto che il file non esisteva, anche se sembrava che lo fosse. Il problema era che Windows 7 era configurato per "Nascondi le estensioni di file per i tipi di file conosciuti". Ciò significa che se il file sembra avere il nome "data.txt", il suo nome file effettivo è "data.txt.txt".

Spero che questo aiuti gli altri a salvarsi dei capelli.


Non credo che questo fosse il problema nel mio caso. Come menzionato nella mia domanda: "Posso copiare e incollare il percorso completo nella finestra" Esegui "in Windows e il file si apre correttamente.", Il che significa che il file esiste effettivamente.
atsjoo

3

Il new Filecomando crea semplicemente un'istanza di un file utilizzando il nome del percorso specificato. In realtà non crea un file sul disco rigido.

Se dici

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

Può restituire true solo se esisteva un file esistente con lo stesso percorso. Se intendevi controllare lo stesso file dichiarato nella prima riga, potresti doverlo usare in questo modo.

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

Ora questo tornerà vero.


piccola spiegazione: ogni chiamata al costruttore mediante l'uso della nuova parola chiave crea un oggetto - come in questo caso un oggetto descritto dalla classe il cui nome è File! quindi non un'istanza di File! = descrittori :)
ceph3us

3

Se non vuoi gestire le chiamate getAbsoluteFile () ogni volta che devi chiamare un metodo, è meglio creare la tua istanza di file già con un percorso assoluto. Questo dovrebbe fare il trucco:

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

Suggerisco di circondarlo con un blocco try-catch, BTW.


3

Per generalizzare il problema, il problema si pone durante la conversione di URL / URI in percorsi locali.

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

Spero che questo ti aiuti.


2

Quando ["Nascondi le estensioni per i tipi di file conosciuti."] È selezionato, Windows apre "t.txt.txt" quando digita "t.txt" in [explorer] / [esegui windows] ma non a livello di programmazione.


1
Ho avuto questo problema e il problema era che ho creato un file txt, chiamato "testFile.txt", in C: \ test. Ho fatto riferimento a questo file utilizzando il percorso C: \ test \ testFile.txt, che non ha funzionato. Era perché il file era stato effettivamente salvato come testFile.txt.txt, da qui il voto positivo sulla soluzione di cui sopra (Vecchia domanda, ma nessuna risposta accettata!)
Theblacknight

God Windows fa schifo così tanto.
aafc

0

Buone risposte a tutti. Ho scoperto che questo sembra essere un problema con Java che accede alla C:directory principale su Windows. Qualsiasi altra directory dovrebbe andare bene, ma per qualche motivo, menzionare specificamente C:\o C:o C:/potrebbe dare un errore. Ho risolto questo problema molto simile intercettando la menzione new File("C:");e sostituendolo con nuovoFile(System.getProperty("file.separator")); o dovresti essere in grado di codificare "\" invece di dire "c:" come directory dei file e potrebbe funzionare. Non elegante, ma ha fatto il lavoro per me in questo progetto.

Spero possa essere d'aiuto. Potrebbe non essere la soluzione giusta, ma almeno ha funzionato per me. Sono suJRE 1.6, Win 7 . Saluti!

Rispettosamente,

@ Carpenter1010


0

Se le situazioni in cui fallisce comportano l'esecuzione come un altro utente, e sei su Windows Vista / Windows 7, potrebbe essere causato da VirtualStore, il meccanismo in cui Windows consente a un utente non privilegiato di "scrivere" posti che normalmente non può. Le modifiche sono tuttavia memorizzate in "% USERPROFILE% \ AppData \ Local \ VirtualStore \" che sono private per ogni account utente.


1
Sto eseguendo Windows xp x86
atsjoo

0

Quando niente di quanto sopra ha funzionato per me, ho provato

filePath = filePath.trim();

Questo pulirà la tua corda da qualsiasi carattere indesiderato


0

Ultimamente mi sono imbattuto in questo stesso problema. Quello che ho fatto è stato disinstallare Netbeans, la cartella netbeans eliminata dall'unità C, i file di programma, l'aggiornamento, i dati dei programmi, praticamente ovunque. Quindi reinstallare. Ora funziona bene. Non dimenticare di eseguire il backup della cartella del progetto netbeans prima di eseguire le azioni precedenti.

Spero che sia d'aiuto.


0

Con alcuni IDE (potrebbe essere) e / o con alcuni sistemi operativi (es: finestra), per impostazione predefinita non hanno accesso in scrittura sui file. Quindi se provi a fare file.exists () ti mostrerà falso. per risolvere questo problema, fai come di seguito

se la variabile di riferimento per File è f, esempio: File f = new File ("path");

quindi per farlo funzionare, seleziona f con il mouse e poi vai al menu Cerca> Accesso in scrittura> Area di lavoro. Si spera che funzioni.


-2

Penso che dovresti usare invece il backslash, in questo modo:

File file = nuovo file ("C: \\ User \\ utilities \\ data \\ someTextFile.txt"); (due barre rovesciate, non un errore di battitura)

Dovrebbe risolvere il problema :)


3
Penso che il problema sia più correlato al percorso assoluto rispetto al percorso relativo. Le barre sono valide in Java anche per i percorsi Windows.
рüффп
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.