ejemplo - php "glob" y deduplicación de datos?
php glob order (4)
Tengo una aplicación php que está (por solicitud) buscando la existencia de algunos archivos. (en una red compartida)
Estoy usando glob
para esto, porque normalmente solo conozco el principio del nombre de archivo.
Noté que glob
no devuelve archivos, que actualmente están abiertos por cualquier cliente, por lo que mi aplicación cree que file_xy
no existe, si alguien lo ha abierto.
¿Hay alguna manera de hacer que glob
devuelva archivos abiertos (: = bloqueados?) También?
Lo extraño es que esto no se menciona. Sin embargo, puedo confirmar que glob NO está devolviendo archivos, que actualmente están abiertos por un cliente ... (Tan pronto como el cliente cierre la aplicación de acceso, glob
devolverá el archivo como de costumbre)
ps .: ni siquiera glob("//server/share/*")
está devolviendo el archivo mientras esté abierto. (Network Share permite el número máximo de usuarios concurrentes)
$dir = opendir ("//server/share");
while ($file = readdir($dir)){
echo $file."<br />";
}
muestra el archivo en cuestión perfectamente bien, sin importar si lo abrió otro cliente o no. - Así que casi puedo excluir cualquier cosa de límite de acceso / permiso ...
Descubrí la causa incluso si no sé la razón ahora:
Aparece el problema con glob()
no encontrar un archivo abierto, cuando el archivo está ubicado en una unidad que está usando la función de desduplicación de datos de Windows Server 2012 R2.
Si muevo el archivo a un recurso compartido no deduplicado, glob()
puede leerlo, incluso cuando lo abren varios clientes.
Ya que tengo una alternativa de trabajo, esta pregunta debería centrarse principalmente en la pregunta de por qué glob no funciona, o digamos, trabajo diferente aquí. Tiene que haber una diferencia en cómo glob
y readdir
están accediendo al sistema de archivos subyacente para determinar el contenido.
Otra prueba
Hay otra prueba de que esto se relaciona con la deduplicación de datos: configuré la función para "solo" deduplicar archivos con más de 3 días.
Configuré un cronjob, "abriendo y agrupando" un determinado archivo en el recurso compartido. Una vez que tenía ~ 3 días de antigüedad (Windows decide cuándo deduplicar), glob no pudo enumerar el archivo mientras estaba abierto por otro cliente.
Por lo tanto, glob es capaz de encontrar archivos abiertos, que se han copiado en el recurso compartido DENTRO de los primeros 3 días, y luego comienza a extrañarlos, una vez que se ha deduplicado.
Observaciones
glob
glob
falla, provocando este post :-)
scandir
Usar la función de scandir
mencionada muestra el mismo comportamiento:
- archivo deduplicado abierto por un cliente - falta en la matriz resultante.
- archivo deduplicado no abierto por un cliente - parte de la matriz resultante.
opendir / readdir
Quiero subrayar de nuevo, que opendir
junto con readdir
funciona en ambos casos.
RecursiveDirectoryIterator
Esto produjo el resultado esperado en cualquier momento también.
Atributos de archivo
Noté que los archivos deduplicados se muestran con un "Tamaño en el disco duro" de 0 bytes, mientras que los archivos aún no deduplicados (que se encuentran con éxito) se muestran con el tamaño que ocupan lógicamente (según el tamaño de los sistemas de archivos):
Sin embargo, esto no explicaría por qué es importante que un cliente abra un archivo o no. Informe de tamaño es igual en cualquier momento.
¿Te preparas para usar otra función que glob()
? Puede intentar usar los iteradores recursivos de SPL si encuentra un archivo abierto que se encuentra en una unidad que está usando la función de desduplicación de datos de Windows Server 2012 R2. Puedes encontrar un ejemplo de cómo puedes usarlo desde este enlace.
Esto tiene sentido si la intención de la deduplicación no es tener duplicados, entonces los archivos se están bloqueando y PHP no puede verlos. Lo único que hay que hacer es ver si esta limitación se aplica a scandir () y también a la familia de iteradores de directorio / sistema de archivos SPL. Si es así, puede que no sea posible obtener una lista de ellos.
La única otra opción sería usar exec () y una línea de comandos de Windows para ver si puede obtener una lista de archivos y luego analizar la salida. Esto puede ser útil
¡Buena suerte!
Has probado
$files = glob(''{,.}*'', GLOB_BRACE);
Es posible que la función de eliminación de datos mantenga el archivo abierto como un archivo oculto.
No estoy seguro de si esto es lo que está buscando, pero uso scandir () para enumerar todos los archivos en un directorio, luego puede ejecutar cualquier comando en ellos una vez que sepa el nombre. También funcionará en archivos abiertos