Tengo un proceso de Java que abre un archivo usando un FileReader. ¿Cómo puedo evitar que otro proceso (Java) abra este archivo, o al menos notificar a ese segundo proceso que el archivo ya está abierto? ¿Esto automáticamente hace que el segundo proceso obtenga una excepción si el archivo está abierto (lo que resuelve mi problema) o tengo que abrirlo explícitamente en el primer proceso con algún tipo de indicador o argumento?
Para aclarar:
Tengo una aplicación Java que enumera una carpeta y abre cada archivo en la lista para procesarlo. Procesa cada archivo tras otro. El procesamiento de cada archivo consiste en leerlo y hacer unos cálculos basados en el contenido y demora unos 2 minutos. También tengo otra aplicación Java que hace lo mismo, pero escribe en el archivo. Lo que quiero es poder ejecutar estas aplicaciones al mismo tiempo para que el escenario sea así. ReadApp enumera la carpeta y busca los archivos A, B, C. Abre el archivo A e inicia la lectura. WriteApp enumera la carpeta y encuentra los archivos A, B, C.Abre el archivo A, ve que está abierto (por una excepción o de cualquier manera) y va al archivo B. ReadApp finaliza el archivo A y continúa hasta B. Ve que está abierto y continúa en C. Es crucial que WriteApp no t escriba mientras ReadApp está leyendo el mismo archivo o viceversa. Son procesos diferentes.
Respuestas:
FileChannel.lock es probablemente lo que desea.
(Descargo de responsabilidad: código no compilado y ciertamente no probado).
Tenga en cuenta la sección titulada "dependencias de la plataforma" en el documento API para FileLock .
fuente
FileOutputStream
).FileOutputStream
no será de mucha utilidad para unReader
.NonWritableChannelException
, porquelock()
intenta adquirir un bloqueo exclusivo, pero eso requiere acceso de escritura. Si tiene un flujo de entrada , puede usar ellock(0L, Long.MAX_VALUE, false)
que adquiere un bloqueo compartido y solo requiere un acceso de lectura. También puede usar un modoRandomAccessFile
abierto en lectura-escritura si desea un bloqueo exclusivo mientras lee ... pero eso prohibiría los lectores concurrentes.lock(0L, Long.MAX_VALUE, true)
, nolock(0L, Long.MAX_VALUE, false)
. el último argumento esboolean shared
docs.oracle.com/javase/8/docs/api/java/nio/channels/…No use las clases en el
java.io
paquete, en su lugar use eljava.nio
paquete. Este último tiene unaFileLock
clase. Puede aplicar un bloqueo a unFileChannel
.fuente
Si puede usar Java NIO ( JDK 1.4 o superior ), creo que está buscando
java.nio.channels.FileChannel.lock()
FileChannel.lock ()
fuente
File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine
use java.nio.channels.FileLock junto con java.nio.channels.FileChannel
fuente
Puede que esto no sea lo que está buscando, pero con el interés de abordar un problema desde otro ángulo ...
¿Son estos dos procesos Java los que podrían querer acceder al mismo archivo en la misma aplicación? ¿Quizás puede filtrar todo el acceso al archivo a través de un único método sincronizado (o, mejor aún, usando JSR-166 )? De esa forma, puede controlar el acceso al archivo y tal vez incluso poner en cola las solicitudes de acceso.
fuente
Use un RandomAccessFile, obtenga su canal, luego llame a lock (). El canal proporcionado por los flujos de entrada o salida no tiene suficientes privilegios para bloquearse correctamente. Asegúrese de llamar a unlock () en el bloque finalmente (cerrar el archivo no necesariamente libera el bloqueo).
fuente
A continuación se muestra un código de fragmento de muestra para bloquear un archivo hasta que JVM realice su proceso.
fuente