一些背景资料
我想下载的文件在外部服务器上保存一周,并且每小时都会在那里创建一个新的 XML 文件(10-50mb 大),名称不同。我希望每次加载我的网站时在后台将大文件逐块下载到我的服务器,每次可能 0.5mb,然后在下次其他人加载网站时恢复下载。这将要求我的网站每小时至少有 100 个页面加载以保持更新,因此如果可能的话,每次可能会增加更多的文件。我研究了 simpleXML , XMLreader , SAX parsing,但无论我做什么,直接解析文件似乎需要很长时间,因此我想要一种不同的方法,即像上面描述的那样下载它。
如果我下载一个 30mb大的 XML 文件,我可以在 3 秒内使用 XMLreader 在本地解析它(25 万次迭代),但是当我尝试从外部服务器执行相同操作时,将其限制为 5 万次迭代,它使用 15 秒来读取那个小文件部分,因此似乎无法直接从该服务器解析它。
可能的解决方案
我认为最好使用cURL。但话又说回来,也许fopen()、fsockopen()、copy()或file_get_contents()是要走的路。我正在寻找关于使用哪些函数来实现这一点的建议,或者关于如何将 50mb 外部 XML 文件解析为mySQL数据库的不同解决方案。
我怀疑每小时执行一次Cron作业是最好的解决方案,但我不确定虚拟主机公司对它的支持程度如何,我也不知道如何做这样的事情。但如果这是最好的解决方案,而且大多数人都这么认为,我也必须在该领域进行研究。
如果在后台运行的java applet/javascript是一个更好的解决方案,那么当涉及到那里的函数/方法/库时,请指出正确的方向。
概括
- 在后台下载部分文件并在每次加载我的网站直到完成时恢复下载的最佳解决方案是什么?
- 如果即使尝试上述解决方案也很愚蠢,您会使用什么语言/软件来实现相同的目标(每小时下载一个大文件)?
提前感谢所有答案,对于长篇大论/问题深表歉意。
编辑:我最终使用此解决方案来获取具有 cron 作业调度 php 脚本的文件。它检查我的文件夹中已有的文件,生成过去四天可能下载的列表,然后下载下一个 XML 文件。
<?php
$date = new DateTime();
$current_time = $date->getTimestamp();
$four_days_ago = $current_time-345600;
echo 'Downloading: '."\n";
for ($i=$four_days_ago; $i<=$current_time; ) {
$date->setTimestamp($i);
if($date->format('H') !== '00') {
$temp_filename = $date->format('Y_m_d_H') ."_full.xml";
if(!glob($temp_filename)) {
$temp_url = 'http://www.external-site-example.com/'.$date->format('Y/m/d/H') .".xml";
echo $temp_filename.' --- '.$temp_url.'<br>'."\n";
break; // with a break here, this loop will only return the next file you should download
}
}
$i += 3600;
}
set_time_limit(300);
$Start = getTime();
$objInputStream = fopen($temp_url, "rb");
$objTempStream = fopen($temp_filename, "w+b");
stream_copy_to_stream($objInputStream, $objTempStream, (1024*200000));
$End = getTime();
echo '<br>It took '.number_format(($End - $Start),2).' secs to download "'.$temp_filename.'".';
function getTime() {
$a = explode (' ',microtime());
return(double) $a[0] + $a[1];
}
?>
编辑2:我只是想告诉你,有一种方法可以按照我的要求做,只是在我的情况下它不起作用。有了我需要的数据量,该网站每小时必须有 400 多名访问者才能正常工作。但是对于较少量的数据,有一些选择;http://www.google.no/search?q=poormanscron