2

Why open file is deleted? On Windows Xamp, I get message "still working", but on other PHP serwer file is deleted, even if it is open and I get message "file deleted". I can delete file from FTP too, even if first script is still working :(

<?php
$handle = fopen("resource.txt", "x");
sleep(10);
?>


<?php
if (file_exists("resource.txt") && @unlink("resource.txt") === false) {
    echo "still worning";
    exit;
}
else
    echo "file deleted";
?>
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
user3433519
  • 31
  • 1
  • 3
  • Why delete it when it is opened? – Alma Do Apr 25 '14 at 08:30
  • If file is opened using fopen, it doesn't mean it's **protected** in any way. – N.B. Apr 25 '14 at 08:32
  • So why it works on Windows and Xamp? But not on external PHP server? I use @unlink to check that script is still working. At the begining of one script a open "resource.txt" and in second file I check every 1 second that script is still executing. – user3433519 Apr 25 '14 at 08:33
  • 1
    Have you ever read that Linux/Unix systems behave exactly like Windows? – N.B. Apr 25 '14 at 08:35

1 Answers1

7

UNIX systems typically let you do this, yes. The underlying C unlink function is documented as such:

The unlink() function removes the link named by path from its directory and decrements the link count of the file which was referenced by the link. If that decrement reduces the link count of the file to zero, and no process has the file open, then all resources associated with the file are reclaimed. If one or more process have the file open when the last link is removed, the link is removed, but the removal of the file is delayed until all references to it have been closed.

In other words, you can basically mark the file for deletion at any time, but the system will actually keep it around as long as applications are still accessing it. Only when all applications have let go of the file will it finally actually be removed. Windows apparently does not do it that way. Update: Since PHP 7.3 it's now possible to unlink open files.

As a side note, UNIX' behaviour is the only sane behaviour in a multi-process environment. If you have to wait for all processes to close access to a file before the system lets you remove it, it's basically impossible to remove frequently accessed files at all. Yes, that's where those Windows dialog boxes about "Cannot delete file, still in use, retry?" come from which you can never get rid of.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • So, is there possibility to make my script working? So is there any option to check that file is still open? – user3433519 Apr 25 '14 at 08:40
  • 1
    It *is* "working" already, but your understanding of what it should do it different. ;) You probably want to be [`flock`ing](http://php.net/flock) your file. – deceze Apr 25 '14 at 08:41