2009-08-13 11 views
26

La mia piccola applicazione di utilità chiede all'utente una directory di output tramite un selettore di file GUI. Quindi crea molti file in questa directory di output dopo qualche elaborazione.Controllo dell'accesso in scrittura in una directory prima di creare file al suo interno

ho bisogno di controllare se l'applicazione ha accesso in scrittura in modo che informa l'utente e non non continuare con la lavorazione (che potrebbe richiedere molto tempo)

Il mio primo tentativo è stata la CanWrite() metodo di java.io.File. Ma questo non funziona poiché si occupa della stessa voce della directory e non del suo contenuto. Ho visto almeno un'istanza di una cartella di Windows XP che può essere rinominata o cancellata ma non è possibile creare alcun file (a causa delle autorizzazioni). Questo è in realtà il mio banco di prova.

finalmente si stabilirono con la seguente soluzione

//User places the input file in a directory and selects it from the GUI 
//All output files will be created in the directory that contains the input file 
File fileBrowse = chooser.getSelectedFile(); //chooser is a JFileChooser 
File sample = new File(fileBrowse.getParent(),"empty.txt"); 
try 
{ 
    /* 
     * Create and delete a dummy file in order to check file permissions. Maybe 
     * there is a safer way for this check. 
     */ 
     sample.createNewFile(); 
     sample.delete(); 
} 
catch(IOException e) 
{ 
     //Error message shown to user. Operation is aborted 
} 

Tuttavia, questo non si sente elegante per me dal momento che cerca solo di creare effettivamente un file e controlla se l'operazione riesce.

Ho il sospetto che ci debba essere un modo migliore per questo, ma tutte le soluzioni che ho trovato fino ad ora con Security Manager e cose che riguardano le applet Java e non le applicazioni standalone. Mi manca qualcosa?

Qual è il modo consigliato di verificare l'accesso ai file all'interno di una directory prima che stia effettivamente scrivendo i file?

Sto usando Java 5.

+0

Cosa succede se "empty.txt" esiste già? Quindi si finisce per cancellare un file che potrebbe essere stato importante. –

+0

Sì, sarebbe meglio se il valore booleano restituito da createNewFile() fosse usato per capire se il file è stato effettivamente creato da no. – kazanaki

risposta

19

Si potrebbe verificare i permessi dei file, assicurarsi che esista la directory, e fare un sacco di controllo o di trovare una libreria che fa tutto quello che il controllo per si MA (!) non è il modo migliore per verificare? Se controlli le autorizzazioni e il filesystem cambia ... dovrai cambiare il tuo codice. Ma provando a scrivere un file ti dirà SEMPRE se puoi scrivere un file.

La tua soluzione non deve essere la più elegante. Non è una patch scadente con codice o qualcosa di brutto. È solo un codice normale. E funzionerà sempre. Ma se non ti piace vedere quel controllo nel codice, basta separarlo mettendolo in classe il cui unico obiettivo è verificare la possibilità di scrivere. In effetti, dovresti metterlo in una classe di utilità a cui ti piace l'eleganza o meno.

L'altra soluzione sarebbe quella di inserire l'intero codice di scrittura sul disco rigido, nel tentativo. E se non puoi scrivere, l'intera parte verrà saltata e tu fornirai un feedback all'utente con un messaggio nella parte catch.

0

non funziona anche se si richiama canWrite sul percorso finale?

File sample = new File(fileBrowse.getParent(),"empty.txt"); 

if (sample.canWrite()) { 
    doSomethingUseful(sample); 
} else { 
    notifyUser(); 
} 
+4

Non perché canWrite verifica anche se il file esiste. Questo non è il caso del tuo codice. È menzionato nel javadoc. – kazanaki

0

è possibile utilizzare FilePermission per ottenere i dettagli. Trovo un modo in cui è necessario implementare SecurityManager il codice è here e here

+0

Ho guardato FilePermission ma mi sembra che sia usato in Applet per garantire l'accesso ai file. Hai un esempio con applicazioni standalone? – kazanaki

0

Direi di concentrarsi sul fornire una buona esperienza utente se/quando il file non può essere scritto, e semplicemente non preoccuparsi di pre-controllare il percorso.Dal momento che dici che l'elaborazione richiede un po 'di tempo, non c'è modo di garantire che sarai ancora in grado di scrivere su quel percorso quando finisce. Le autorizzazioni potrebbero cambiare molto tra quando si controlla e quando si scrive, o il disco potrebbe riempire, o ...

0

Utilizzo di Java 1.8 Sono stato in grado di utilizzare quanto segue.

Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(Paths.get(destDir), LinkOption.NOFOLLOW_LINKS); 
Assert.assertTrue("User did not have read permission.", permissions.contains(PosixFilePermission.OWNER_READ)); 
Assert.assertTrue("User did not have execute permission.", permissions.contains(PosixFilePermission.OWNER_EXECUTE)); 
Assert.assertTrue("User did not have write permission.", permissions.contains(PosixFilePermission.OWNER_WRITE)); 

Assert.assertFalse("Group did have read permission.", permissions.contains(PosixFilePermission.GROUP_READ)); 
Assert.assertFalse("Group did have execute permission.", permissions.contains(PosixFilePermission.GROUP_EXECUTE)); 
Assert.assertFalse("Group did have write permission.", permissions.contains(PosixFilePermission.GROUP_WRITE)); 

Assert.assertFalse("Others did have read permission.", permissions.contains(PosixFilePermission.OTHERS_READ)); 
Assert.assertFalse("Others did have execute permission.", permissions.contains(PosixFilePermission.OTHERS_EXECUTE)); 
Assert.assertFalse("Others did have write permission.", permissions.contains(PosixFilePermission.OTHERS_WRITE)); 
Problemi correlati