Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305

    [JAVA] Determinare causa dell'errore FileNotFoundException

    Salve dell'eccezione FileNotFoundException ne esistono tre varianti, ovvero quando il file non esiste , quando il file è utilizzato da un altro processo e un' altra che non ricordo. Adesso vorrei chiedervi come posso fare in fase di runtime a verificare quale delle tre eccezioni si è verificata? Avevo pensato a un if sul messaggio di errore ma è poco elegante . Sapreste darmi qualche altro consiglio?.
    Praticamente ho un watch listener su una directory, quando ci copio un file esso interviene, solo che a volte interviene prima che il sistema operativo abbia finito di copiare completamente il file nella directory.
    Come posso fare??
    Ultima modifica di linux_r; 10-02-2014 a 13:42

  2. #2
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305
    C'è nessuno??

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Non è fattibile.
    Una FileNotFoundException può essere sollevata per questi motivi:

    1) Il file non esiste (o il percorso al file è sbagliato)
    2) Il file è usato da un altro processo (in caso di richiesta di apertura in scrittura)
    3) Se non si hanno i permessi per accedere al file


    Per poter risalire alla causa è necessario indagare lo stackTrace: solo lì c'è scritto chi è che ha sollevato l'eccezione, ma questo ti permette solo di capire se si tratta della terza ipotesi o no. Nel caso si ricada in una delle prime due, non hai modo di capirlo se non andando ad indagare sul codice sorgente che ha generato l'eccezione e cercando di capire quale file si sta cercando di aprire, per quali scopi e, infine, andando a vedere effettivamente questo file.

    Farlo programmaticamente è un suicidio privo di senso: il gioco non vale la candela, molto meglio visualizzare un messaggio che dica all'utente "E' successo questo. Le cause possibili sono: ...".

    Per il debug o per aiutare il programmatore ad identificare il problema è utile permettere all'utente (tramite una finestra, tramite un file di log o altro) di visualizzare lo stackTrace completo.


    PS: credo possano esistere anche altre cause, legate al file-system.


    Ciao.
    Ultima modifica di LeleFT; 12-02-2014 a 13:53
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305
    Ok , il problema mio è che mi metto in ascolto su una cartella , ogni volta che c'è un nuovo file lo devo leggere, solo che a volte il software java è talmente veloce da aprire il file prima che windows abbia finito di copiarlo !! come posso fare?

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Se possibile, usa dei semafori.
    L'applicativo che scrive il file dovrebbe scriverne un secondo (con lo stesso nome, diversa estensione, ad esempio) solo quando ha completato il file.

    Così tu rimani in ascolto dei file con estensione ".ack" (ad esempio) e quando ne trovi uno, sai che esiste un file con lo stesso nome da andare a leggere.

    Alternativa più semplice, il semaforo inverso: l'applicativo scrive subito un file di lock, che eliminerà solo quando il file di dati sarà pronto.

    Alternativa delle alternative: se ottieni una FileNotFoundException per un file che sai che "dovrebbe esistere" (immagino che tu effettui un list della directory), allora lo metti in una "coda tentativi" e lo lasci stare... quindi riprovi più tardi.

    Non conosco ancora bene la libreria NIO, ma forse lì c'è qualcosa di più efficiente. Provo a vedere.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  6. #6
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305
    forse non sono stato chiaro . Il mio applicativo java instanzia un listener directory e ogni qualvolta che avviene un evento di inserimento di un nuovo file sulla directory registrata, allora devo aprire il nuovo file e leggerne il contenuto . Il problema è questo: i nuovi file vengono messi nella directory utilizzando il sistema operativo, ma l'applicativo java non attende che siano copiati interamente e quindi tenta di aprirli e a solleva l'eccezione filenotfoundexception , il file è utilizzato da un altro processo. Le tiue idee sono ottime se non fosse per il fatto che l'applicativo che scrive il file è il sistema operativo.

  7. #7
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Immaginavo che non fosse un tuo applicativo a scrivere i file... quindi ti rimangono 2 strade:

    1) La coda tentativi (brutta e poco applicabile)

    2) La tecnologia NIO, che ti spiego qui sotto.

    Tramite tecnologia NIO puoi cercare di acquisire un lock esclusivo su un file (su un FileChannel, per la verità).
    Se riesci ad acquisire il lock, allora:

    1) Il file c'è (ovvio, hai un FileChannel)
    2) Hai i permessi per manipolarlo
    3) Nessuno sta usando quel file
    4) Nessuno lo userà finchè tu ne detieni il lock

    Questo è garanzia del fatto che puoi leggere il file. Se non riesci ad acquisirne il lock, allora qualcosa non va bene e non puoi usare quel file.

    Qui un abbozzo (non provato) di come procedere:

    codice:
    File f = ...   // E' il file che devo provare a leggere
    
    // Apro il file in lettura (già qui, se ho un'eccezione, so che non devo procedere oltre)
    FileInputStream fis = new FileInputStream( f );
    
    // Ottengo il FileChannel
    FileChannel channel = fis.getChannel();
    
    // Provo ad acquisire il lock sul file
    FileLock lock = channel.tryLock();
    if (lock != null) {
       // Ho ottenuto il lock, posso lavorare col file
       ...
    
       // Ho finito di lavorare col file, rimuovo il lock
       lock.release();
       ...
    } else {
       // Non ho ottenuto il lock, qualcun altro sta usando il file...
    }

    Sul cosa fare in caso di eccezioni e/o lock non acquisiti, a te la scelta.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  8. #8
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305
    ti ringrazio ma sta soluzione gia l'avevo provata però non mi risolve il problema , avrei bisogno tipo di qualcosa di bloccante che se il file è in uso da un altro processo attendo che si liberi senza sollevare eccezione

  9. #9
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Quote Originariamente inviata da linux_r Visualizza il messaggio
    ti ringrazio ma sta soluzione gia l'avevo provata però non mi risolve il problema , avrei bisogno tipo di qualcosa di bloccante che se il file è in uso da un altro processo attendo che si liberi senza sollevare eccezione

    Beh... è piuttosto semplice:

    codice:
    // Provo ad acquisire il lock sul file e attendo finchè non ci riesco
    FileLock lock = null;
    
    while(lock == null) {
       lock = channel.tryLock();
       if (lock == null) {
          // Attendo 2 secondi
          try {
             Thread.sleep( 2000 );
          } catch (InterruptedException ie) {
             ie.printStackTrace();
          }
       }
    }
    
    // Qui ci arrivo solo quando avrò effettivamente il lock
    ...   // fai quel che vuoi col file, che tanto è tuo.

    Non è una soluzione "ottimale" perchè in questo caso potresti rimanere "appeso" all'infinito (se non riesce ad ottenere il lock perchè impossibile)... conviene prevedere un meccanismo che consenta l'uscita se passa "troppo tempo" (il troppo tempo lo decidi tu).


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  10. #10
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305
    si ma per ottenere il channel bisogna istanziare il fileinputstream e se il file è utilizzato da un altro processo si solleva l'eccezione filenotfoundexception !!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.