Pregunta

Estoy tratando de bloquear un archivo con Java en el entorno de Windows con FileLock y tengo un problema: después de bloquear el archivo todavía se puede acceder a otros procesos al menos en algún nivel.

Ejemplo de código siguiente:

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();
    }
}

Ahora, cuando me bloqueo mi archivo con este ejemplo, está bloqueada:

  • No se puede eliminar por Windows
  • Eclipse se niega a abrirlo

... pero no es todavía totalmente a prueba de balas:

  • Si lo abro con Scite (un editor de texto), por ejemplo, no se muestra ningún contenido, pero si selecciono para guardar el archivo (vacío como abierto o con algún contenido escrito), tiene éxito y el contenido del archivo se limpiado ... (sin contenido existe allí después incluso si había escrito algo con Scite)

¿Hay alguna manera de evitar que el archivo completo de la sobrescritura / despejado por otros procesos con Java en Windows?

Si lo he entendido bien, lo estoy usando exclusiva atm bloqueo. Con bloqueo compartido hay aún más cosas que se pueden hacer.

Esta prueba se realizó con Windows 2000.

br, Touko

¿Fue útil?

Solución

Tricky, el propio API FileLock no promete mucho:

  

Esta API de bloqueo de archivos se pretende   asignar directamente al bloqueo nativo   instalación del operativo subyacente   sistema. Por lo tanto los bloqueos mantenidos en un archivo   debe ser visible para todos los programas que   tener acceso al archivo, independientemente de   el idioma en que esos programas   están escritos.

     

Si o no un bloqueo en realidad   impide que otro programa desde   acceder al contenido del bloqueada   región es dependiente del sistema y   por lo tanto, no especificado. El nativo   instalaciones de bloqueo de archivos de algunos   Los sistemas son meramente consultiva, lo que significa   que los programas deben cooperativamente   observar un protocolo de bloqueo conocido en   Para garantizar la integridad de los datos. En   otros sistemas de cerraduras de archivo nativos son   obligatoria, lo que significa que si un programa   Bloquea una región de un archivo y luego otra   programas se llegó a impedir la   el acceso a esa región de una manera que   violaría la cerradura. En todavía otra   sistemas, si son bloqueos de archivo nativo   asesoramiento u obligatoria es configurable   en función de cada archivo. Para asegurar   un comportamiento coherente y correcta a través   plataformas, se recomienda encarecidamente   que los cierres proporcionados por esta API sean   utilizado como si fueran bloques de consulta.

Por extraño que parezca, la discusión sobre el archivo de API cuando estaba en el desarrollo de bloqueo afirmaron que el sistema operativo Windows proporciona obligatorio bloqueo y en Unix única de bloqueo de asesoramiento. Así en que la lectura se podría esperar que su código funcione muy bien en Windows.

Me pregunto si lo que está sucediendo es que el editor no está modificando tanto el archivo como la creación de un archivo temporal y luego manipular entradas de directorio con el fin de REPLCE la versión del archivo que se ha bloqueado con una nueva versión. Sería de Windows permitir que este tipo de comportamiento?

Me pregunto si será necesario recurrir a la JNI con el fin de obtener el nivel de control que desee.

Otros consejos

Su llamada a .tryLock () puede devolver un valor nulo si no consigue la cerradura. Desde el Javadoc:

  

A objeto de bloqueo que representa la cerradura recién adquirido, o null si el bloqueo no puede ser adquirido porque otro programa mantiene un bloqueo superposición

Además, el código actualmente abre el archivo y que intenta adquirir un bloqueo. En su lugar debe bucle tratando de conseguir la cerradura, y una vez que lo tienes, abre el archivo, lee el archivo, cierre el archivo, y luego renunciar a la cerradura. Y renunciar a la cerradura en una cláusula finally {}, en caso de que el código emita una excepción con el bloqueo mantenido. (Alguna vez tuvo que reiniciar una máquina Windows sólo porque un archivo fue bloqueado?)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top