Forum Moderators: coopster

Message Too Old, No Replies

Deleting a file from disk after a download

Create / Download / Delete - best method?

         

trillianjedi

9:58 am on Feb 5, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi guys,

I've got a new service on a website which involves dynamically creating a binary file (which is an installation package) for a user to download.

I want to then clean-up by deleting the file after it's been downloaded.

Problem is while it's being downloaded I can't delete it.

I'm sure I'm not the first person to come up against this. Anyone have some thought as to the best method to achieve the desired result? I can think of three ways:-

1. Have the PHP script that served the download block by trying to get an FLOCK on the file. Then delete.

2. Use outbound buffering to serve the file from memory, having deleted it from disk first.

3. Use a CRON job to clean up disk files every 5 mins or so

Problem with 1 and 3 is they just "feel" like an ugly hack to me. Problem with 2 is the downloaded file can be up to 18mb in size, so could eat up RAM quite quicky.

Pseudo code looks something like this:-

click_me_to_download.php

// Build the application
$path = buildPersonalCopyOfMegaApp($username from a cookie);

// Ship it to client
readfile($path);

// Delete the file from disk
deletefile($path); <-- fails as we need to wait for the download to finish

Any thoughts?

Thanks!

surrealillusions

11:21 am on Feb 5, 2008 (gmt 0)

10+ Year Member



is this file been downloaded to the users computer or stored in a session on the browser?

If its saved to the users computer, then i dont think it is possible to delete the file.

:)

joelgreen

11:52 am on Feb 5, 2008 (gmt 0)

10+ Year Member



Hi. This is the code i have in my download script. It sends file by chunks, checking if connection not broken. Think you should be able to delete the file if you put "unlink" or something after this code.

$file = fopen($file_path,"rb");
if ($file) {
while(!feof($file)) {
print(fread($file, 1024*8));
flush();
if (connection_status()!=0) {
fclose($file);
break;
}
}
fclose($file);
}

henry0

12:41 pm on Feb 5, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Couldn't you base it on reading the result of a progess bar script then del when done?

I have seen a bunch of those dealing with file d-loads and progress bar

trillianjedi

12:45 pm on Feb 5, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for the input guys.

Joel - that looks like it might be the ticket - thanks, will try it and report back...

or stored in a session on the browser?

No, it's a download (binary file).

whoisgregg

2:47 pm on Feb 5, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Nevermind, just realized you already proposed the cron method. Doh! :/

whoisgregg

3:02 pm on Feb 5, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I just did a test with a PHP script that makes a duplicate of a 50MB file, sends it to the user, then unlinks it. It waited for the download to complete before unlinking it... so perhaps your pseudo code is fine since the script would have sent all the data to the user before it gets to the line where you delete the file?

<?php
$pathtooriginal = $_SERVER['DOCUMENT_ROOT'].'/play/download-delete/original.tif';
$pathtoduplicate = $_SERVER['DOCUMENT_ROOT'].'/play/download-delete/'.uniqid().'.tif';
copy($pathtooriginal, $pathtoduplicate);
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($pathtoduplicate));
header('Content-Disposition: attachment; filename=' . basename($pathtoduplicate));
readfile($pathtoduplicate);
unlink($pathtoduplicate); // doesn't execute until readfile() is finished
?>

Of course, my test was over a LAN, so perhaps this would fail if the download speed was slower?

coopster

5:12 pm on Feb 5, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I use readfile(). You can also check the return value from readfile() to take appropriate action -- perhaps you want to log errors, etc.