2012-08-29 8 views
5

Estoy buscando una solución Necesito eliminar archivos de registro, pero podría haber una posibilidad de que se acceda en el momento en que se realiza la llamada de eliminación. Al acceder, quiero decir que un proceso es leer o escribir en el archivo. En tales casos, debo omitir el archivo en lugar de eliminarlo. También mi servidor es Linux y PHP se ejecuta en Apache.Eliminar archivo si actualmente no se está accediendo

Lo que estoy buscando es algo similar a (in pseudo-code):

<?php 
$path = "path_to_log_file"; 
$log_file = "app.log"; 
if(!being_accessed($log_file)) 
{ 
    unlink($path.$log_file); 
} 
?> 

Ahora mi pregunta es ¿cómo puedo definir being_accessed? Sé que podría no haber una función de lenguaje para esto directamente en PHP. Estoy pensando en usar una combinación de secciones como last_access_time (tal vez?) Y flock (pero esto sólo es útil en aquellas condiciones donde el archivo se flock -ed por la aplicación que accede)

Cualquier sugerencia/penetraciones dan la bienvenida ...

+0

cómo se define el archivo "siendo accedido"? –

+0

Puede haber un proceso ya sea leyéndolo o escribiéndolo ... –

+1

no importa en Linux, los archivos no se eliminarán hasta que se cierren todos los punteros de archivo. – SirDarius

Respuesta

6

En general, no podrá encontrarlo sin tener derechos de administración (es decir, podrá ejecutar herramientas como lsof para ver si su archivo está en la lista. Pero si sus scripts se ejecutan en el servidor linux/unix (que es el caso para la mayoría de los hosters) entonces no necesita molestarse, porque el sistema de archivos se encargará de esto. Por ejemplo, usted tiene un archivo de 1GB y alguien está descargando este archivo. Es seguro para usted eliminar el archivo (con unlink() o de cualquier otro tipo) si el descargador acaba de iniciarse y no interferirá con su descarga, porque el sistema de archivos sabe que el archivo ya está abierto (algunos procesos tienen un asa) por lo que solo lo marcará, digamos invisible para otros (entonces Si intenta listar el contenido de la carpeta, ya no verá ese archivo, pero si su archivo es lo suficientemente grande, podría intentar verificar el espacio disponible en el disco (es decir, con df, para ver que todavía estaría ocupado)) pero aquellos que mantienen el identificador todavía podrán usarlo. Una vez que todos los procesos cierren, su archivo de manejador se eliminará físicamente de los medios y el espacio de disco liberado. Así que solo desvincula cuando sea necesario. Si te molestas en la advertencia unlink puede tirar (que puede haber un caso en Windows), entonces simplemente escriba su llamada con @ marca (@unlink()) para desactivar cualquier advertencia esta llamada puede lanzar en tiempo de ejecución

+0

¿Será la eliminación una llamada de bloqueo en tales casos? Al igual que si un proceso está escribiendo en un bucle, y hay una llamada de eliminación en su contra ... ¿eliminará el bloque hasta que finalice el proceso de escritura? –

+1

No. 'unlink' se devolverá inmediatamente, como si nadie estuviera usando ese archivo. –

+0

¡Suena perfecto para lo que estoy haciendo, gracias! –

1

Se podría simplemente cambiar su código de esta manera (si lo está haciendo de forma repetitiva):

<?php 
$path = "path_to_log_file"; 
$log_file = "app.log"; 
@unlink($path.$log_file); 

Aviso de la @ para evitar un error en caso de que el archivo no es eliminable, y la falta de etiqueta de cierre (que termina etiquetas son fuente de errores comunes y deben se debe evitar)

Cuestiones relacionadas