在后台从外部源下载大型XML文件,如果不完整,则可以恢复下载

时间:2012-04-18 17:44:14

标签: php file curl stream

一些背景信息

我要下载的文件在外部服务器上保留一周,每小时创建一个新的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

2 个答案:

答案 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);
?>