1

全部,

我已经建立了一个表格,如果用户填写表格,我的代码可以确定该用户需要下载哪些(大)文件。我用下载按钮显示每个文件,我想在按钮旁边显示该文件的下载状态(下载正在进行、取消/中止或完成)。因为文件很大(200 MB+),所以我使用一个众所周知的函数来读取要以块下载的文件。我的想法是记录数据库中每个(100 KB)块的读取,这样我就可以跟踪下载进度。我的代码如下:

    function readfile_chunked($filename, $retbytes = TRUE) 
    {
          // Read the personID from the cookie 
          $PersonID=$_COOKIE['PERSONID'];
          // Setup connection to database for logging download progress per file
          include "config.php";
          $SqlConnectionInfo= array    ( "UID"=>$SqlServerUser,"PWD"=>$SqlServerPass,"Database"=>$SqlServerDatabase);
          $SqlConnection= sqlsrv_connect($SqlServer,$SqlConnectionInfo);
          ChunckSize=100*1024; // 100 kbyte buffer
          $buffer = '';
          $cnt =0;
          $handle = fopen($filename, 'rb');
          if ($handle === false) 
          {
                return false;
          }
          $BytesProcessed=0;
          while (!feof($handle)) 
          {
                 $buffer = fread($handle, $ChunckSize);
                 $BytesSent = $BytesSent + $ChunckSize;
                 // update database
                 $Query= "UPDATE [SoftwareDownload].[dbo].[DownloadProgress] SET     LastTimeStamp = '" . time() . "' WHERE PersonID='$PersonID' AND FileName='$filename'";
                 $QueryResult = sqlsrv_query($SqlConnection, $Query);
                 echo $buffer;
                 ob_flush();
                 flush();
                 if ($retbytes) 
                 {
                        $cnt += strlen($buffer);
                 }
          }
          $status = fclose($handle);
          if ($retbytes && $status) 
          {
                 return $cnt; // return num. bytes delivered like readfile() does.
          }
          return $status;
    }

奇怪的是,我的下载以恒定的速度平稳运行,但我的数据库会以峰值更新:有时我会在一秒钟内看到几十个数据库更新(所以是几十个 100 KB 块),下一刻我看到没有数据库更新(因此 PHP 没有提供 100 k 块)长达一分钟(此超时取决于可用于下载的带宽)。一分钟内没有写入任何进度的事实使我的代码认为下载已中止。与此同时,我看到 IIS 的内存使用量在增加,因此我认为 IIS 会缓冲 PHP 提供的数据块。我的网络服务器在 FastCGI 模式下运行 Windows 2008 R2 数据中心(64 位)、IIS 7.5 和 PHP 5.3.8。有什么我可以做的(在我的代码中,在我的 PHP 配置或 IIS 配置中)以防止 IIS 缓存 PHP 传递的数据,或者如果生成的数据实际传递到下载客户端,是否有任何方法可以在 PHP 中查看?提前致谢!

4

2 回答 2

1

由于没有找到有用的答案,我通过严格使用 Apache 来下载文件创建了一个真正狡猾的解决方法。整个表单、CSS 等仍然通过 IIS 传递,只是下载链接是由 Apache 提供的服务器(反向代理服务器位于中间,所以用户不必摆弄端口号,代理会处理这个)。Apache 不缓存 PHP 输出,因此我在数据库中获得的时间戳是可靠的。

于 2012-06-18T09:16:42.783 回答
0

我曾经问过一个类似的问题,并在那里得到了很好的答案。

基本上,您使用 APC 缓存来缓存变量,然后使用来自客户端的 Ajax 调用在不同的页面中检索它。

另一种可能性是对数据库做同样的事情。将进度写入数据库并让客户端使用 Ajax 调用对其进行测试(假设每秒)。

于 2012-04-13T09:44:24.160 回答