2015-05-29 19 views
11

Sto cercando di determinare se un file esiste in una cartella di rete:Perché il ritorno 'File.exists' vero, anche se '' Files.exists in classe il NIO 'Files' restituisce falso

// File name is "\\QWERTY\folder\dir\A123456.TXT" 
Path path = Paths.get("\\\\QWERTY\\folder\\dir\\A123456.TXT") 

utilizzando NIO Files:

Files.exists(path) == false 

utilizzando File:

path.toFile().exists() == true 

utilizzando File sembra essere esimo e corretto uno secondo i nostri test. Perché lo File funziona meglio di Files?

Quindi, qual è? Non possono essere entrambi!

Ma aspettate, c'è anche Files.notExists(path).

Quando il file di condivisione di rete esiste effettivamente

Files.exists(path): false 
Files.notExists(path): false 
path.toFile().exists(): true 

Quando il file di condivisione di rete realmente fa non esiste

Files.exists(path): false 
Files.notExists(path): true 
path.toFile().exists(): false 

Un altro modo altrettanto folle di guardare il tre risultati sopra

: smileyFace:

Ambiente e commenti

Il programma è in esecuzione su un 8.1 Pro macchina a 32 bit di Windows (OS e la macchina) e il controllo su una condivisione di rete da un Windows 2008 R2 (32 bit) macchina.

Per determinare che Files.exists era fallito, ho installato un WatchService per controllare la cartella e ho visto che il file esisteva quando Files.exists stava controllando. Ho quindi effettuato il login come entrambi i metodi e ho trovato che File.exists era quello corretto.

Ora, nel mio codice ho l'assegno come Files.exists(path) || path.toFile().exists().

sembra Kinda stupido per avere a che fare entrambe le cose. Probabilmente potrebbe cavarsela solo dopo. Sto solo cercando di dare agli ingegneri di Oracle il beneficio del dubbio, ma l'intera faccenda è piuttosto sciocca che riportano diversi.

Inoltre, non mi importa se 'esiste' è subito superato. Voglio solo sapere se il file esiste nell'istante in cui stiamo controllando. Non mi sono mai imbattuto in questo - abbiamo appena trascorso 30 ore tra me e un altro sviluppatore cercando di capire perché i nostri programmi non si interfacciano a causa di questa 'funzione'.

Meditate su questo un po '

File.exists(): restituisce true se e solo se esiste il file o la directory contrassegnati da questo percorso astratto; falso altrimenti.

Files.exists(): restituisce true se il file esiste; false se il file non esiste o la sua esistenza non può essere determinata.

che le crepe me up! "se e solo se il file o la directory indicati da questo percorso astratto esiste, falso altrimenti" è in contrasto con "true se il file esiste, false se il file non esiste o non è possibile determinarne l'esistenza"

Quindi, come può ancora File.exists essere vero se "l'esistenza non può essere determinata"? Ovviamente, l'esistenza può essere (ed è in corso) determinata dal File ma non da File.

+0

'Fils.exists' documenta zione: 'Nota che il risultato di questo metodo è immediatamente superato. Se questo metodo indica che il file esiste, non vi è alcuna garanzia che un accesso di successione abbia esito positivo. Prestare attenzione quando si utilizza questo metodo in applicazioni sensibili alla sicurezza. Questo potrebbe essere il problema, soprattutto su una rete. – user1803551

+1

@ user1803551, sono abbastanza certo che sia vero anche per l'altro, non c'è alcuna garanzia in entrambi i casi che qualcuno non cancelli il file tra il controllo e l'utilizzo. – paxdiablo

+0

@paxdiablo Bene. – user1803551

risposta

4

Per quanto riguarda il motivo per cui ci può essere una differenza tra i due, contrastare la loro documentazione:

File.exists(): restituisce vero se e solo se esiste il file o la directory indicata con questo percorso astratto; falso altrimenti.

Files.exists(): restituisce true se il file esiste; false se il file non esiste o la sua esistenza non può essere determinata.

Questo potrebbe forse spiegare la differenza tra i due, forse il Files uno sta avendo problemi di accertare l'esistenza del file.

Per esempio, sotto Linux, è possibile configurare file e directory i permessi in modo tale che è possibile aprire un file che esiste ma non può vedere che esiste (togliendo l'autorizzazione di lettura sulla directory del file è dentro lasciando i permessi dei file più aperti).

Come da more of Oracle's documentation, Files.exists() restituisce solo true se il file è verificato esistere.

Un valore restituito di false fa non significa che non esiste.

essi suggeriscono di utilizzare sia exists() e notExists() per coprire le tre possibilità, qualcosa di simile:

if (Files.exists(fspec)) { 
    System.out.println("It exists!"); 
else if (Files.notExists(fspec)) { 
    System.out.println("It does not exist!"); 
else 
    System.out.println("I have no idea!"); 

che copre le tre possibilità di stato del file coperti in quel link qui sopra:

  • Il file è verificato che esista.
  • Il file è verificato per non esiste.
  • Lo stato del file è sconosciuto. Questo risultato può verificarsi quando il programma non ha accesso al file.
+1

In realtà, è corretto nel mio codice, l'ho appena digitato male nell'esempio. Grazie per averlo visto. Corretto. –

+1

Allora perché "File # exists" restituisce true? La documentazione specifica che "true * se e solo se * il file o la directory indicati da questo percorso astratto esiste;" –

+0

Quindi il mio testo "che può o no". – paxdiablo

0

Ho avuto lo stesso problema, ma il tuo hack non mi ha aiutato.Quando il file è stato effettivamente esiste tutti i metodi mi ha restituito falso:

Files.exists(path) = false, 
path.toFile().exists() = false, 
Files.notExists(path) = true, 
Files.exists(path) || path.toFile().exists() = false 

Ma se in questo momento l'esploratore una directory di rete con questo file è stato aperto, allora la sua esistenza è stata correttamente gestita

ho risolto questo problema creazione di un nuovo file nella directory (quindi eliminarlo):

Files.createFile(Paths.get(path.getParent().toString(), "test")); 

dopo questo comando, a quanto pare, le informazioni di aggiornamento di Windows sulla cartella