2009-02-26 16 views
8

Quiero abrir un archivo que otra aplicación escribe periódicamente. Esta aplicación no puede ser modificada. Por lo tanto, me gustaría abrir el archivo solo cuando sé que no está escrito en otra aplicación.Python: ¿cómo comprobar si un archivo es utilizado por otra aplicación?

¿Hay alguna manera pitónica de hacer esto? De lo contrario, ¿cómo logro esto en Unix y Windows?

editar: Lo intentaré y aclararé. ¿Hay alguna manera de verificar si otra aplicación ha abierto el archivo actual?

Me gustaría comenzar con esta pregunta. Si esa otra aplicación de lectura/escritura es irrelevante por ahora.

Me doy cuenta de que probablemente sea dependiente del sistema operativo, por lo que puede que esto no esté realmente relacionado con Python en este momento.

+0

¿Está tratando de lograr la rotación de registros? – vladr

+0

No exactamente, pero no demasiado lejos. Quiero construir una aplicación encima de una existente. –

Respuesta

7

¿Su script de python desea abrir el archivo para escribir o leer? ¿La aplicación heredada se está abriendo y cerrando el archivo entre escrituras, o lo mantiene abierto?

Es extremadamente importante que entendamos lo que hace la aplicación heredada y lo que su secuencia de comandos python está intentando lograr.

Esta área de funcionalidad depende mucho del sistema operativo, y el hecho de que no tenga control sobre la aplicación heredada solo hace que las cosas sean más difíciles por desgracia. Si la forma de hacerlo es pitónica o no, probablemente sea la menor de tus preocupaciones: la pregunta difícil será si lo que estás tratando de lograr será posible.


ACTUALIZACIÓN

OK, por lo que conocer (de su comentario) que:

el uso de la herencia está abriendo y cerrar el archivo cada X minutos, pero no lo hago quiero suponer que en t = t_0 + n * X + eps ya cerró el archivo.

Luego, se modifican los parámetros del problema. En realidad, se puede hacer de una manera independiente del sistema operativo dadas algunas suposiciones, o como una combinación de técnicas dependientes del sistema operativo y técnicas independientes del sistema operativo. :)

  1. forma independiente del sistema operativo: si es seguro asumir que el uso de la herencia mantiene el archivo abierto por un máximo de cierta cantidad de tiempo conocido, por ejemplo T segundos (por ejemplo, se abre el archivo, realiza una escritura , luego cierra el archivo) y lo vuelve a abrir más o menos cada X segundos, donde X es mayor que 2 * T.
    • stat el archivo
    • restar la hora de modificación del archivo desde now(), produciendo D
    • si T < = D < X a continuación, abra el archivo y hacer lo que tiene con ella
    • esto puede ser lo suficientemente seguro para su aplicación. La seguridad aumenta a medida que disminuye T/X. En * nix, es posible que deba verificar dos veces /etc/ntpd.conf para ver la configuración correcta de paso por el tiempo en lugar de la configuración de giro (consulte el programa Tinker). Para Windows ver MSDN
  2. de Windows: además de (o en lugar) del método independiente del sistema operativo anterior, es posible que intente utilizar ya sea:
    • compartir (bloqueo): esto supone que el programa heredado también abre el archivo en modo compartido (generalmente el predeterminado en las aplicaciones de Windows); Además, si su aplicación adquiere el bloqueo justo cuando la aplicación heredada está intentando lo mismo (condición de carrera), la aplicación heredada fallará.
      • esto es extremadamente intrusivo y propenso a errores. A menos que la nueva aplicación y la aplicación heredada necesiten acceso sincronizado para escribir en el mismo archivo y esté dispuesto a manejar la posibilidad de que se le niegue la apertura de un archivo a la aplicación heredada, no utilice este método.
    • intentar averiguar qué archivos están abiertos en el uso de la herencia, utilizando las mismas técnicas que ProcessExplorer (el equivalente a * de nix lsof)
      • son aún más vulnerables a las condiciones de carrera que el OS- técnica independiente
  3. Linux/etc.: además de (o en lugar) del método independiente del sistema operativo anterior, puede intentar utilizar la misma técnica que lsof o, en algunos sistemas, sólo tiene que comprobar qué archivo del enlace simbólico /proc/<pid>/fd/<fdes> puntos a
    • se son aún más vulnerables a las condiciones de carrera que la técnica independiente del sistema
    • es muy poco probable que la aplicación heredada use bloqueo, pero si lo es, el bloqueo no es una opción real a menos que la aplicación heredada pueda manejar un archivo bloqueado bloqueo, no por falla, y si su propia aplicación puede garantizar que el archivo no permanecerá bloqueado, bloqueando la aplicación heredada durante periodos de tiempo prolongados.)

ACTUALIZACIÓN 2

Si favoreciendo la "comprobar si el uso de la herencia tiene el archivo abierto" (método intrusivo propensos a condiciones de carrera), entonces se puede resolver dicha raza condición por:

  1. comprobando si la aplicación heredada tiene el archivo abierto (a la lsof o ProcessExplorer)
  2. suspendiendo el proceso de solicitud heredado
  3. repitiendo la comprobación en el paso 1 para confirmar que la aplicación heredada no abrió el archivo entre los pasos 1 y 2; demore y reinicie en el paso 1 si es así; de lo contrario, vaya al paso 4
  4. haciendo su negocio en el archivo; idealmente simplemente renómbrelo para un procesamiento independiente posterior para mantener la aplicación heredada suspendida por un período de tiempo mínimo
  5. reanudando el proceso de solicitud heredado
+0

La aplicación heredada está abriendo y cerrando el archivo cada X minutos, pero no quiero suponer que en t = t_0 + n * X + eps ya cerró el archivo. –

0

Unix no tiene bloqueo de archivos de forma predeterminada. La mejor sugerencia que tengo para un entorno Unix sería mirar las fuentes para el comando lsof. Tiene un conocimiento profundo sobre qué proceso tienen qué archivos abrir. Podrías usar eso como la base de tu solución. Aquí están los Ubuntu sources for lsof.

+0

Parece que puede ser una buena solución en Unix. Puedo analizar el resultado de lsof para el archivo que necesito antes de acceder a él. No es completamente seguro sin un candado, pero puedo manejar la corrección solo en el 99.99% de los casos. Solo necesito una solución para Windows también. –

0

Una cosa que he hecho es hacer que python cambie el nombre del archivo temporalmente. Si podemos cambiarle el nombre, entonces ningún otro proceso lo está usando. Solo probé esto en Windows.

+1

Me viene a la mente la frase "condición de carrera": - / –

Cuestiones relacionadas