cesarcesar Posted February 9, 2011 Share Posted February 9, 2011 I'm using the following script to download large file (>100Mb). It works well except that it seems to not ever save the final chunk. If the file is 149,499 on the server, it finishes its download at 145,996. Why? How do I get the last 2% or so to flush and complete the download? Thank much for your help. FYI, this also happens the same on smaller files so its not stopping for time or file size issues. $path = "the/file/path.mp4"; $headsize = get_headers($path,1); $ext = str_from_last_occurrence($_vars['filepath'],"."); if ($ext=="mp3") { $type = "audio"; } elseif ($ext=="mp4") { $type = "video"; } function readfile_chunked($filename,$retbytes=true) { // Stream file $handle = fopen($filename, 'rb'); $chunksize = 1*(1024*1024); // how many bytes per chunk $buffer = ''; $cnt =0; if ($handle === false) { return false; } while (!feof($handle)) { $buffer = fread($handle, $chunksize); 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; } header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate'); header("Content-type: ".$type."/".$ext); header('Content-Length: ' . (string)($headsize['Content-Length'])); header('Content-Disposition: attachment; filename="'.str_from_last_occurrence($_vars['filepath'],"/").'"'); header("Content-Transfer-Encoding: binary"); readfile_chunked($path); exit; Quote Link to comment Share on other sites More sharing options...
btherl Posted February 9, 2011 Share Posted February 9, 2011 What byte count does your function return? Quote Link to comment Share on other sites More sharing options...
cesarcesar Posted February 9, 2011 Author Share Posted February 9, 2011 How would I determine the byte count? Quote Link to comment Share on other sites More sharing options...
btherl Posted February 9, 2011 Share Posted February 9, 2011 $bytes_sent = readfile_chunked($path); print "We send $bytes_sent bytes"; There may be an issue here with seeing that message, so you may have to disable the "echo $buffer;" line and all the header() calls temporarily. Another thing to check - is the content-length header being set correctly? Try printing out $headsize['Content-Length'], it should be the exact length of the file. Quote Link to comment Share on other sites More sharing options...
cesarcesar Posted February 9, 2011 Author Share Posted February 9, 2011 $bytes_sent = readfile_chunked($path); print "We send $bytes_sent bytes"; We send 149499083 bytes Try printing out $headsize['Content-Length'], it should be the exact length of the file. 149499083 Quote Link to comment Share on other sites More sharing options...
btherl Posted February 10, 2011 Share Posted February 10, 2011 Ok.. so it is sending the correct length in the header, and it is sending the correct number of bytes.. Can you try adding this line, just before the exit: readfile_chunked($path); sleep(1); exit; I want to see if giving a bit of extra time before the script finishes will make a difference. It shouldn't, but it's worth a try. BTW have you posted the entire script or just part of it? Quote Link to comment Share on other sites More sharing options...
cesarcesar Posted February 10, 2011 Author Share Posted February 10, 2011 adding the sleep didnt effect anything. Yes that is the whole script. Quote Link to comment Share on other sites More sharing options...
btherl Posted February 10, 2011 Share Posted February 10, 2011 Hmm.. well I don't see what could be going wrong. You can remove ob_flush(), that's not doing anything, unless something is secretly switching on output buffering before your script runs. Have you tried readfile() or fpassthru() instead? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.