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

Как определить, переносится ли файл через ftp

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

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

4b9b3361

Ответ 1

Наш администратор сервера предложил ftpwho, который выводит файлы, которые в настоящий момент переносятся.

http://www.castaglia.org/proftpd/doc/ftpwho.html

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

Ответ 2

Один из самых безопасных способов сделать это - загрузить файлы с временным именем и переименовать их после завершения передачи. Программа должна пропускать файлы с временным именем (простое расширение работает просто отлично). Очевидно, для этого требуется, чтобы клиент (загрузчик) сотрудничал, поэтому он не идеален.

[Это также позволяет удалять неудачные (частичные) передачи по истечении заданного периода времени, если вам это нужно.]

Все, что основано на опросе размера файла, является ярким и небезопасным.

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

Что-то, что не требует сотрудничества от клиента, проверяет, открыт ли файл другим процессом или нет. (Как вы это делаете, зависит от ОС - я не знаю встроенного PHP, который делает это. lsof и/или fuser может использоваться на разных платформах Unix-типа, для Windows для этого есть API). Если у другого процесса открыт файл, скорее всего, он еще не завершен.

Обратите внимание, что этот последний подход не может быть безупречным, если вы разрешаете перезапуск/возобновление загрузки или если ваше программное обеспечение FTP-сервера не сохраняет файл открытым в течение всей продолжительности передачи, поэтому YMMV.

Ответ 3

Некоторые FTP-серверы позволяют запускать команды при возникновении определенного события. Поэтому, если ваш FTP-сервер разрешает это, вы можете создать простую схему сигнализации, чтобы ваше приложение узнало, что файл загружен более или менее успешно (более или менее потому, что вы не знаете, должен ли пользователь загружать файл полностью или по частям). Схема сигнализации может быть такой же простой, как создание файла "uploaded_file_name.ext.complete", и вы будете следить за существованием файлов с расширением ".complete".

Теперь вы можете проверить, можете ли вы открыть файл для записи. Большинство FTP-серверов не позволят вам делать это, если файл загружается.

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

Ответ 4

Лучший способ проверить - попытаться получить эксклюзивную блокировку файла с помощью стаи. Процесс sftp/ftp будет использовать библиотеки fopen.

// try and get exclusive lock on file
$fp = fopen($pathname, "r+");

if (flock($fp, LOCK_EX)) {  // acquire an exclusive lock
    flock($fp, LOCK_UN);    // release the lock
fclose($fp);
}
else {
    error_log("Failed to get exclusive lock on $pathname. File may be still uploading.");
}

Ответ 5

Это не очень хороший трюк, но он прост:-), то же самое можно делать с файлом

$result = false;
$tryies = 5;
if (file_exists($filepath)) {
    for ($i=0; $i < $tryies; $i++) { 
        sleep(1);
        $filesize[] = filesize($filepath);
    }
    $filesize = array_unique($filesize);
    if (count($filesize) == 1) {
        $result = true;
    } else {
        $result = false;
    }
}

return $result;