因此,我正在编写一个分块文件传输脚本,旨在将文件(无论大小)复制到远程服务器。它几乎工作得非常好(我测试了一个 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
如果我在 fwrite() 之后立即添加 sleep(1),它似乎可以工作。然而,这使得脚本需要一百万年才能运行。PHP的附加是否有可能存在一些固有的缺陷?
编辑 4
好吧,不知何故,进一步将问题隔离为 FTP 问题。当我在本地运行此文件副本时,它工作正常。但是,当我使用文件传输协议(第 9 行)时,字节丢失了。尽管fopen()
. 这可能是什么原因造成的?
编辑 5
我找到了解决办法。修改后的代码在上面——我会尽快自己发布一个答案。