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

PHP: Как я могу избежать чтения частичных файлов, которые были перенесены мне с FTP?

Файлы перенаправляются на мой сервер через FTP. Я обрабатываю их с помощью PHP-кода в модуле Drupal. O/S - Ubuntu, а FTP-сервер - vsftp.

Через регулярные промежутки времени я буду проверять наличие новых файлов, обрабатывать их с помощью SimpleXML и перемещать их в папку "Готово". Как избежать обработки частично загруженного файла?

vsftp имеет значение lock_upload_files по умолчанию yes. Я думал о попытке сначала перенести файлы, ожидая, что переход произойдет в текущем загружаемом файле. Это, похоже, не происходит, по крайней мере, в командной строке. Если я начну загружать большой файл и перемещаться, он просто продолжает расти в новом месте. Я думаю, что запись в каталоге не заблокирована.

Должен ли я попытаться fopen с режимами 'a' или 'r +' только для того, чтобы убедиться, что это удается, прежде чем пытаться загрузить в SimpleXML или есть лучший способ сделать это? Думаю, я мог просто обнаружить потерю нагрузки SimpleXML, но... это кажется грязным.

У меня нет контроля над отправителем. Они не будут загружать и переименовывать.

Спасибо

4b9b3361

Ответ 1

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

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

Ответ 2

Использование опции lock_upload_files конфигурации vsftpd приводит к блокировке файлов с помощью функции fcntl(). Это помещает предупреждающую блокировку на загруженные файлы (файлы), которые находятся в процессе. Другим программам не нужно рассматривать консультативные блокировки, а mv, например, нет. Консультационные блокировки - это, как правило, только советы для программ, которые заботятся о таких замках. Вам понадобится другой инструмент командной строки, такой как lockrun, который соблюдает консультативные блокировки.

Примечание. lockrun должен быть скомпилирован макросом WAIT_AND_LOCK(fd) для использования функции lockf(), а не flock(), чтобы работать с блокировками, установленными fcntl() под Linux. Поэтому, когда lockrun скомпилируется с использованием lockf(), то он будет взаимодействовать с блокировками, установленными vsftpd.

С такими функциями (lockrun, mv, lock_upload_files) вы можете создать оболочку script или аналогичную, которая перемещает файлы один за другим, проверяя, был ли файл заблокирован заранее, и удерживая на нем консультативную блокировку пока файл перемещен. Если файл заблокирован с помощью vsftpd, то lockrun может пропустить вызов на mv, чтобы пропускать загружаемые загрузки.

Ответ 3

Команда lsof linux перечисляет открытые файлы в вашей системе. Я предлагаю выполнить его с помощью shell_exec() из PHP и проанализировать вывод, чтобы узнать, какие файлы все еще используются вашим FTP-сервером.

Ответ 4

Подбирая предыдущий ответ, вы можете скопировать файл, а затем сравнить размеры скопированного файла и исходного файла с фиксированным интервалом.

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

Если размеры не совпадают, скопируйте файл еще раз.

повторить.

Ответ 5

Вот еще одна идея: создать супер (но, надеюсь, не root) пользователя FTP, который может получить доступ к некоторым или ко всем каталогам загрузки. Вместо того, чтобы ваш PHP-код считывал загруженные файлы с диска, подключите его к локальному FTP-серверу и загрузите файлы. Таким образом vsftpd обрабатывает блокировку для вас (при условии, что вы оставите lock_upload_files включенным). Вы сможете загружать файл только после того, как vsftp освободит блокировку исключительной записи/записи (как только запись завершена).

Вы упомянули попытку flock в своем комментарии (и как это не удается). Это действительно кажется болезненным, чтобы попытаться сопоставить любые блокировки vsftpd, но dio_fcntl может стоить того.

Ответ 6

Я думаю, вы решили свою проблему много лет назад, но все же.

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