2009-04-03 21 views
17

¿Qué sucede cuando simultáneamente abre dos (o más) FileOutputStreams en el mismo archivo?Escritura simultánea de archivos en Java en Windows

El Java API dice esto:

Algunas plataformas, en particular, permitir que se abra un archivo para escritura por un solo FileOutputStream (u otro objeto de archivo-escritura) a la vez.

supongo Windows no es una plataforma de este tipo, porque tengo dos hilos que leen algún archivo grande (cada uno una diferente), entonces escribirlo en el mismo archivo de salida. No se lanza ninguna excepción, el archivo se crea y parece contener fragmentos de ambos archivos de entrada.

preguntas secundarios:

  • es esto cierto para Unix, también?
  • Y como quiero que el comportamiento sea el mismo (de hecho, quiero que un hilo se escriba correctamente y el otro que se lo advierta del conflicto), ¿cómo puedo determinar si el archivo ya está abierto para la escritura?

Respuesta

16

No hay una manera confiable, multiplataforma de ser pasivamente notificado cuando un archivo tiene otro escritor — es decir, levantar una excepción si un archivo ya está abierto para la escritura. Sin embargo, hay un par de técnicas que lo ayudan activamente a verificar esto.

Si varios procesos (que pueden ser una mezcla de Java y otros) pueden estar usando el archivo, use un FileLock. Una clave para usar bloqueos de archivos con éxito es recordar que son solo "asesores". El bloqueo está garantizado para ser visible si lo comprueba, pero no le impedirá hacer cosas en el archivo si lo olvida. Todos los procesos que acceden al archivo deben estar diseñados para usar el protocolo de bloqueo.

Si un proceso de Java único está trabajando con el archivo, puede utilizar las herramientas de simultaneidad integradas en Java para hacerlo de forma segura. Necesita un mapa visible para todos los hilos que asocie cada nombre de archivo con su instancia de bloqueo correspondiente. Las respuestas a a related question se pueden adaptar fácilmente para hacer esto con los objetos File o canonical paths en los archivos. El objeto de bloqueo podría ser un FileOutputStream, un contenedor alrededor de la ruta, o un ReentrantReadWriteLock.

4

Me gustaría no permitir que el sistema operativo determine el estado del archivo (ya que depende del sistema operativo). Si usted tiene un recurso compartido Me restringir el acceso al mismo mediante un Re-entrant lock

El uso de este bloqueo significa un hilo puede obtener el recurso (archivo) y escribir en él. El siguiente subproceso puede comprobar que este bloqueo esté retenido por otro subproceso y/o bloquear indefinidamente hasta que el primer subproceso lo libere.

Windows (creo) restringiría dos procesos escribiendo en el mismo archivo. No creo que Unix haga lo mismo.

+0

Pero no quiero bloquear cada vez que escribo, quiero bloquear, si alguien ya está escribiendo en el archivo que quiero escribir. En realidad, no quiero bloquear nada. Quiero decirle al segundo hilo que no puede escribir y dejar que el cliente decida sobre otras acciones. –

+0

Muelle esa API de bloqueo. Podrá inspeccionar el bloqueo para determinar si alguien más ya lo ha bloqueado (es decir, no bock) y luego decidir qué hacer –

1

Si los 2 hilos de los que está hablando están en la misma JVM, entonces podría tener una variable booleana en algún lugar al que accedan ambos hilos.

1

Unix permite escritores concurrentes en el mismo archivo.

No debe intentar escribir en el mismo archivo más de una vez. Si es así, tiene un defecto de diseño.

Cuestiones relacionadas