我要下载的文件在外部服务器上保留一周,每小时创建一个新的XML文件(10-50mb大),名称不同。我希望每次加载我的网站时,大文件都会在后台通过chunk下载到我的服务器块,每次可能为0.5mb,然后在其他人加载网站时恢复下载。这将要求我的网站每小时至少有100个页面加载以保持更新,因此如果可能的话,每次都可以更多地删除文件。我研究过 simpleXML , XMLreader , SAX解析,但无论我做什么,似乎直接解析文件需要太长时间,因此我我想要一种不同的方法,即如上所述下载它。
如果我下载一个30mb 大型XML文件,我可以在3秒内(250k迭代)用XMLreader在本地解析它,但当我尝试从外部服务器执行相同操作时将其限制为50k次迭代,它使用15secs来读取那个小部分,因此无法直接从该服务器解析它。
我认为最好使用 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];
}
?>
edit2:我只是想告诉你,有一种方法可以做我所问的,只是在我的情况下它不起作用。根据我需要的数据量,网站每小时必须有400多名访问者才能正常工作。但是,由于数据量较小,有一些选择; http://www.google.no/search?q=poormanscron
答案 0 :(得分:1)
您需要有一个预定的离线任务(例如,cronjob)。你所追求的解决方案是完全错误的。
最简单的事情可能是你每小时运行一次的php脚本(最有可能通过cron安排)下载文件并对其进行处理。
答案 1 :(得分:0)
你可以试试fopen:
<?php
$handle = fopen("http://www.example.com/test.xml", "rb");
$contents = stream_get_contents($handle);
fclose($handle);
?>