Domanda

Sto cercando di bloccare un file con Java in ambiente Windows con FileLock e ho avuto un problema: dopo chiudo il file può ancora essere raggiunto da altri processi, almeno a un certo livello.

Esempio di codice seguente:

public class SimpleLockExample {
    public static void main(String[] args) throws Exception {
        String filename = "loremlipsum.txt";

        File file = new File(filename);
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        FileChannel channel = raf.getChannel();

        FileLock lock = null;
        try {
            lock = channel.tryLock();
            String firstLine = raf.readLine();
            System.out.println("First line of file : " + firstLine);
            waitForEnter();
            lock.release();
        } catch (OverlappingFileLockException e) {
            e.printStackTrace();
        }

        lock.release();
        System.out.println("Lock released");

        channel.close();
    }

    private static void waitForEnter() throws Exception {
        BufferedReader reader =
                new BufferedReader(new InputStreamReader(System.in));
        reader.readLine();
        reader.close();
    }
}

Ora, quando chiudo il mio file con questo esempio, è bloccato:

  • Non può essere eliminato da Windows
  • Eclipse si rifiuta di aprirlo

... ma non è ancora del tutto a prova di proiettile:

  • Se apro con Scite (un editor di testo), ad esempio, nessun contenuto viene visualizzato, ma se seleziono per salvare il file (vuoto come già letto o con alcuni contenuti scritti), riesce e il contenuto del file è cancellato ... (nessun contenuto esiste lì in seguito, anche se avessi scritto qualcosa con Scite)

C'è un modo per evitare che il file totalmente dalla sovrascrittura / eliminato da altri processi con Java in Windows?

Se ho capito bene, che sto utilizzando in esclusiva atm di blocco. Con blocco condiviso ci sono ancora più cose che si possono fare.

Questo test è stato eseguito con Windows 2000.

br, Touko

È stato utile?

Soluzione

Tricky, il FileLock API per sé non promette molto:

  

Questa API blocco file destinato a   mappare direttamente al blocco nativo   facilità del operativo sottostante   sistema. Così i blocchi mantenuti su un file   dovrebbe essere visibile a tutti i programmi che   avere accesso al file, indipendentemente dal   la lingua in cui questi programmi   sono scritti.

     

O se non un blocco in realtà   impedisce un altro programma   l'accesso al contenuto della bloccato   regione dipende dal sistema e   pertanto non specificato. il nativo   strutture di blocco dei file di alcuni   sistemi sono meramente consultivo, il che significa   che i programmi devono cooperativo   osservare un noto protocollo di blocco in   Per garantire l'integrità dei dati. Sopra   altri sistemi di file nativi serrature sono   obbligatorio, nel senso che se un programma   blocca una regione di un file poi altri   i programmi sono in realtà impedito di   Accedendo tale regione in un modo che   violerebbe la serratura. D'altro ancora   sistemi, se blocchi di file nativo sono   consultivo o obbligatoria è configurabile   su una base per-file. Per garantire   un comportamento coerente e corretto in tutta   piattaforme, è fortemente raccomandato   che i blocchi forniti da questa API essere   utilizzati come se fossero blocchi di consulenza.

Stranamente, la discussione sul blocco dei file API quando era in fase di sviluppo ha affermato che il sistema operativo Windows fornito obbligatoria di blocco e su Unix solo bloccaggio consultivo. Così via che la lettura ci si potrebbe aspettare il codice per lavorare bene su Windows.

Mi chiedo se quello che sta succedendo è che l'editor non è tanto la modifica del file come la creazione di un file temporaneo e poi manipolare le voci di directory per REPLCE la versione del file è stato bloccato con una nuova versione. Sarebbe di Windows permettere tale comportamento?

Mi chiedo se è necessario ricorrere a JNI al fine di ottenere il livello di controllo necessario.

Altri suggerimenti

La chiamata a .tryLock () può restituire null se non ottiene il blocco. Dal Javadoc:

  

Un oggetto di blocco che rappresenta la serratura di nuova acquisizione, oppure nullo se la serratura non può essere acquisito perché un altro programma mantiene un lock sovrapposizione

Inoltre, il codice attualmente apre il file e quindi si cerca di acquisire un blocco. Invece si dovrebbe circuito cercando di ottenere il blocco, e una volta che ce l'hai, aprire il file, leggere il file, chiudere il file, quindi rinunciare alla serratura. E rinunciare al blocco in una clausola finally {}, nel caso in cui il codice genera un'eccezione con la serratura tenuta. (Mai avuto riavviare una macchina Windows solo perché qualche file è stato bloccato?)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top