Как обнаружить, что файл загружается по FTP

Мое приложение отслеживает набор папок, где пользователи могут загружать файлы. Когда загрузка файла завершена, я должен применить обработку, но я не знаю, как обнаружить, что файл не закончил загрузку.

Любой способ обнаружить, если файл еще не освобожден FTP-сервером?

Ответ 1

Там нет общего решения этой проблемы.

Некоторые FTP-серверы блокируют загружаемый файл, предотвращая доступ к нему, пока файл все еще загружается. Например, сервер IIS FTP делает это. Большинство других FTP-серверов этого не делают. См. Мой ответ в разделе " Предотвращение доступа к файлу при загрузке".


Есть несколько распространенных способов решения этой проблемы (изначально размещенных в механизме блокировки файлов SFTP, но относящихся и к FTP):

  • Вы можете сделать так, чтобы клиент загрузил "готовый" файл после завершения загрузки. Заставьте свою автоматизированную систему подождать, пока "готовый" файл появится
  • Вы можете иметь выделенную папку "upload", и клиент (атомарно) переместит загруженный файл в "done" папку. Сделайте так, чтобы ваша автоматизированная система смотрела только на папку "готово".
  • Иметь соглашение об именовании файлов для загружаемых файлов (".filepart") и клиент (атомарно) переименовывает файл после загрузки в его окончательное имя. Заставьте свою автоматизированную систему игнорировать файлы ".filepart".
    См. (Мою) статью " Блокировка файлов при загрузке/выгрузке во временное имя файла" для примера реализации этого подхода.
  • Грубый взлом состоит в том, чтобы периодически проверять атрибуты файла (размер и время) и считать загрузку завершенной, если атрибуты не изменились в течение некоторого промежутка времени.

Некоторые FTP-серверы позволяют вам настроить ловушку для вызова, когда загрузка завершена. Вы можете использовать это. Например, ProFTPD имеет модуль mod_exec (см. Директиву ExecOnCommand).

Ответ 2

Я использую ftputil для реализации этого обходного пути:

  1. подключиться к ftp серверу
  2. перечислить все файлы каталога
  3. вызовите stat() для каждого файла
  4. подождите N секунд
  5. Для каждого файла: вызовите stat() еще раз. Если результат отличается, пропустите этот файл, так как он был изменен в течение последних секунд.
  6. Если результат stat() не отличается, загрузите файл.

Вся эта загрузка ftp - старая и устаревшая технология. Я надеюсь, что клиент в следующий раз будет использовать современный http API :-)

Ответ 3

Если вы читаете файлы определенных расширений, используйте WINSCP для передачи файлов. Он создаст временный файл с расширением .filepart, и он вернется к фактическому расширению файла после полной передачи файла.

Надеюсь, это поможет кому-то.

Ответ 4

Это классическая проблема с FTP-передачами. Единственный в основном надежный метод, который я нашел, - это отправить файл, а затем отправить второй короткий "маркерный" файл, чтобы сообщить получателю, что передача первого завершена. Вы можете использовать соглашение об именах файлов и просто проверить наличие второго файла.

Вы можете получить фантазию и сделать содержимое второго файла контрольной суммой первого файла. Затем вы можете проверить первый файл. (У вас нет проблемы со вторым файлом, потому что вы просто дождались размера файла = контрольной суммы).

И, конечно, это работает, только если вы можете отправить отправителю второй файл.