PHP - у фрагментированной копии файла (через FTP) отсутствуют байты?
Итак, я пишу сценарий передачи фрагментированных файлов, предназначенный для копирования файлов - маленьких и больших - на удаленный сервер. Он почти фантастически работает (и работал с 26-байтовым файлом, который я тестировал, хаха), но когда я начинаю делать большие файлы, я замечаю, что он не совсем работает. Например, я загрузил 96 489 231 байт, но окончательный размер файла составил 95 504 152 байт. Я протестировал его с 928 670 754 байтовым файлом, и скопированный файл имел только 927 902 792 байта.
Кто-нибудь еще испытывал это? я догадываюсь feof()
может быть, что-то шатается, но я понятия не имею, как это заменить или проверить это. Я прокомментировал код, для вашего удобства.:)
<?php
// FTP credentials
$server = CENSORED;
$username = CENSORED;
$password = CENSORED;
// Destination file (where the copied file should go)
$destination = "ftp://$username:$password@$server/ftp/final.mp4";
// The file on my server that we're copying (in chunks) to $destination.
$read = 'grr.mp4';
// If the file we're trying to copy exists...
if (file_exists($read))
{
// Set a chunk size
$chunk_size = 4194304;
// For reading through the file we want to copy to the FTP server.
$read_handle = fopen($read, 'rb');
// For appending to the destination file.
$destination_handle = fopen($destination, 'ab');
echo '<span style="font-size:20px;">';
echo 'Uploading.....';
// Loop through $read until we reach the end of the file.
while (!feof($read_handle))
{
// So Rackspace doesn't think nothing's happening.
echo PHP_EOL;
flush();
// Read a chunk of the file we're copying.
$chunk = fread($read_handle, $chunk_size);
// Write the chunk to the destination file.
fwrite($destination_handle, $chunk);
sleep(1);
}
echo 'Done!';
echo '</span>';
}
fclose($read_handle);
fclose($destination_handle);
?>
РЕДАКТИРОВАТЬ
Я (возможно) подтвердил, что сценарий как-то умирает, а не портит файлы. Я создал простой файл с каждой строкой, соответствующей номеру строки, до 10000, а затем запустил свой скрипт. Он остановился на строке 6253. Однако сценарий по-прежнему возвращает "Готово!" в конце, так что я не могу себе представить, что это проблема тайм-аута. Странный!
РЕДАКТИРОВАТЬ 2
Я подтвердил, что проблема существует где-то в fwrite()
, Повторяя $chunk
внутри цикла полный файл возвращается без сбоев. Однако записанный файл все равно не совпадает.
РЕДАКТИРОВАТЬ 3
Кажется, это работает, если я добавлю sleep(1) сразу после fwrite(). Однако это заставляет сценарий работать миллион лет. Возможно ли, что приложение PHP имеет какой-то свойственный недостаток?
РЕДАКТИРОВАТЬ 4
Хорошо, далее изолировал проблему как проблему FTP, так или иначе. Когда я запускаю эту копию файла локально, она работает нормально. Однако, когда я использую протокол передачи файлов (строка 9), байты отсутствуют. Это происходит несмотря на двоичные флаги двух случаев fopen()
, Что может быть причиной этого?
РЕДАКТИРОВАТЬ 5
Я нашел исправление. Измененный код выше - я выложу ответ самостоятельно, как только смогу.
1 ответ
Я нашел исправление, хотя я не уверен точно, почему это работает. Простой сон после записи каждого куска устраняет проблему. Я немного увеличил размер куска, чтобы ускорить процесс. Хотя это возможно плохое решение, оно должно работать для моих целей. В любом случае, ребята, спасибо!