Подтвердить что ты не робот

Как узнать, завершен ли файл на сервере с помощью FTP?

У меня есть приложение сканера файлов в Java, которое продолжает сканировать каталог на сервере с помощью FTP. получает список файлов каталога и загружает их один за другим. с другой стороны, на сервере есть процесс, который записывает эти файлы. если мне повезет, я бы не попытался загрузить неполный файл, но как я могу убедиться, что процесс записи на сервере завершен, и дескриптор файла закрыт, и файл готов к загрузке?

У меня нет контроля над процессом записи, который находится на сервере. кроме того, у меня нет разрешения на запись в каталоге, чтобы попытаться получить дескриптор записи, чтобы проверить, открыт ли дескриптор записи, поэтому этот параметр отключен от таблицы.

Есть ли функция FTP, решая эту проблему?

4b9b3361

Ответ 1

Это очень старая и хорошо известная проблема.

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

Если возможно, программа, обрабатывающая файл, должна иметь дело с частичными файлами.

Гораздо лучшей альтернативой является rsync, который является гораздо более надежным и детерминированным. Его можно даже настроить (с помощью опции командной строки) для первоначальной записи данных во временное местоположение и переместить его на конечный путь назначения после успешного завершения. Если файл существует там, где вы его ожидаете, он по определению завершен.

Ответ 2

Возможное решение: сначала загрузить файл с другим именем файла (например, добавить ".partial" ), а затем переименовать его в свое окончательное имя.

Если сервер находит окончательное имя, загрузка завершена.

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

То, что будет воспринимать принимающая сторона, - это просто закрытие входящего потока; нет никакого способа гарантировать, что данные не будут частичным переносом.

Другими обходными методами могут быть проверки маркера конца данных или использование запроса на отправляющий сервер для проверки того, была ли (по их мнению) передача завершена.

Ответ 3

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

Если вы не можете изменить процесс записи, вам нужно перепрыгнуть через несколько обручей. Нет, это здорово, но некоторые более безопасны, чем другие.

  • Продолжайте читать, пока ничего не изменится для какого-либо окна (может быть, минут, как предлагает Дэвид Шварц). Вы можете немного оптимизировать это, просмотрев размер файла.
  • Выясните, хранятся ли файлы последовательно в надежном порядке. Когда вы увидите файл N, вы знаете, что файл N-1 готов. (Предполагается, что каталог пуст до того, как файлы будут записаны, хотя вы также можете посмотреть временные метки.) Недостатком является то, что ваша логика сломается, если автор когда-либо изменит порядок или начнет писать параллельно.

Надежные, безопасные решения требуют улучшения процесса записи.

  • Writer может записывать файлы в скрытые или временные местоположения и делать их видимыми только после того, как весь файл (или каталог) готов, используя символические ссылки или перемещение файлов или chmod.
  • Writer создает специальный файл (например, "./DONE" ) только после того, как все остальные файлы были записаны, и читатель не читает файлы до тех пор, пока этот файл не появится.
  • В зависимости от типа файла, писатель может добавить некоторую запись/строку конца файла в конце файла, и читатель может убедиться, что он присутствует.

Ответ 4

Вы можете использовать библиотеку Ftp из общего API Apache получить дополнительную информацию

 boolean flag = retrieveFile(String remote, OutputStream local);

Этот выходной поток проверки флажка доступен для текущего файла.