Cómo detectar que un archivo se está cargando a través de FTP

Mi aplicación está vigilando un conjunto de carpetas donde los usuarios pueden cargar archivos. Cuando termina la carga de un archivo, tengo que aplicar un tratamiento, pero no sé cómo detectar que un archivo no ha terminado de cargarse.

¿Hay alguna manera de detectar si el servidor FTP aún no ha lanzado un archivo?

No hay una solución genérica para este problema.

Algunos servidores FTP bloquean el archivo que se está cargando, impidiéndole el acceso mientras se está cargando el archivo. Por ejemplo, el servidor FTP de IIS hace eso. La mayoría de los otros servidores FTP no. Ver mi respuesta en Evitar que se acceda al archivo mientras se está cargando .

Hay algunas soluciones comunes para el problema (publicadas originalmente en el mecanismo de locking de archivos SFTP , pero también relevantes para el FTP):

  • Puede hacer que el cliente cargue un archivo “hecho” una vez que termine la carga. Haga que su sistema automatizado espere a que aparezca el archivo “listo”.
  • Puede tener una carpeta de “carga” dedicada y hacer que el cliente (atómicamente) mueva el archivo cargado a una carpeta “finalizada”. Haga que su sistema automatizado se vea solo en la carpeta “hecho”.
  • Tenga una convención de nombres de archivo para los archivos que se cargan (“.filepart”) y haga que el cliente (atómicamente) cambie el nombre del archivo después de cargarlo a su nombre final. Haga que su sistema automatizado ignore los archivos “.filepart”.
    Ver (mi) artículo Bloquear archivos al cargar / cargar al nombre de archivo temporal para ver un ejemplo de implementación de este enfoque.
  • Un hack bruto es verificar periódicamente los atributos del archivo (tamaño y tiempo) y considerar la carga finalizada, si los atributos no han cambiado durante un intervalo de tiempo.

Algunos servidores FTP le permiten configurar un enganche al que se llamará cuando finalice una carga. Puedes hacer uso de eso. Por ejemplo, ProFTPD tiene un módulo mod_exec (consulte la directiva ExecOnCommand ).

Yo uso ftputil para implementar esta solución alternativa :

  1. conectarse al servidor ftp
  2. enumera todos los archivos del directorio
  3. llame a stat () en cada archivo
  4. espera N segundos
  5. Para cada archivo: llame a stat () nuevamente. Si el resultado es diferente, omita este archivo, ya que fue modificado durante los últimos segundos.
  6. Si el resultado de stat () no es diferente, entonces descargue el archivo.

Todo este ftp-fetching es una tecnología vieja y obsoleta. Espero que el cliente use una http API moderna la próxima vez 🙂

Si está leyendo archivos de extensiones particulares, use WINSCP para transferencia de archivos. Creará un archivo temporal con la extensión .filepart y se convertirá en la extensión real del archivo una vez que haya transferido completamente el archivo.

Espero que ayude a alguien.

Este es un problema clásico con las transferencias FTP. El único método confiable que he encontrado es enviar un archivo, luego enviar un segundo archivo corto de “marcador” solo para decirle al destinatario que la transferencia de la primera está completa. Puede utilizar una convención de nomenclatura de archivos y simplemente verificar la existencia del segundo archivo.

Puede hacerse elegante y hacer que el contenido del segundo archivo sea una sum de comprobación del primer archivo. Entonces podrías verificar el primer archivo. (No tienes el problema con el segundo archivo porque esperas hasta tamaño de archivo = tamaño de sum de comprobación).

Y, por supuesto, esto solo funciona si puede hacer que el remitente envíe un segundo archivo.