http://qs321.pair.com?node_id=761978

deadpickle has asked for the wisdom of the Perl Monks concerning the following question:

Here is a question that I cant seem to answer, even though it is a simple one. I want to simply delete a file, under windows, within perl. I have tried unlink and
my $call = "del $kid"; system($call);
and they delete them, sort of. I know this because I get Could Not Find C:\Users\deadpickle\Desktop\UAS\GRRUVI_1.60\panel\UAS01 in the terminal. But when I go to look at the directory the files 'were' in I am stunned to see that they are still there!!!!! If I ls (yes my windows system has ls) the directory it only verifies that the files were deleted in mind and there bodies are still lingering. I don't get it?! Any ideas?

Replies are listed 'Best First'.
Re: Deleting a File in Windows
by roboticus (Chancellor) on May 05, 2009 at 16:55 UTC
    deadpickle:

    Another possibility: If another job has the file open, then the delete won't work. In my environment (running cygwin under Windows XP), I see this all the time. IIRC, cygwin has a background thread, so if you remove the file, it will actually be deleted after the other processes release the file.

    As an illustration, create a simple text file called zanzibar.txt, and run the following program in a window.

    #!/usr/bin/perl open INF, '<', 'zanzibar.txt' or die $!; sleep 300; close INF or die $!;

    Then, in another window, delete the file. On my system, I see this:

    roboticus@swill$ ls zanzibar.txt roboticus@swill$ rm zanzibar.txt roboticus@swill$ ls zanzibar.txt

    If I wait five minutes and look again, it's gone:

    roboticus@swill$ ls roboticus@swill$
    ...roboticus
Re: Deleting a File in Windows
by ccn (Vicar) on May 05, 2009 at 16:17 UTC
    • Use forward slashes not back slashes in filenames
    • Check return codes to be sure that system call was successful
    unlink("C:/Users/deadpickle/file/to/delete") or die "Can't delete a fi +le\n";
      • deadpickle's path appears well formed, meaning he knows how to escape slashes, so forward slashes aren't needed.
      • Usually you want to know why unlink failed (and on what line)
      my $filename = qw[ C:\Users\deadpickle\Desktop\UAS\GRRUVI_1.60\panel\U +AS01 ]; unlink $filename or die "Couldn't unlink($filename) : ($!)($^E)"; __END__ Couldn't unlink(C:\Users\deadpickle\Desktop\UAS\GRRUVI_1.60\panel\UAS0 +1) : (No such file or directory)(The system cannot find the path spec +ified) at - line 2.
Re: Deleting a File in Windows
by Marshall (Canon) on May 05, 2009 at 17:50 UTC
    Good suggestions from other Monks. Here is a bit more detail on the "file is open" case...A file is just a collection of bits on the disk and a directory entry is just a name associated with those bits. What unlink does is remove that name from the directory - it does not delete bits on the disk.

    "Deleting/Replacing" a file that is in use is a common scenario for say a software upgrade program that is mucking with a shared file like a .dll. If a file like that is open, you can't just copy over it. The way to deal with that is to rename the file, then delete unlink that new name. Then copy in the new say .dll file that has same name as the original. Once a file is open the directory name is irrelevant as the program is using a file handle.

    What happens is that anybody who had that file open continues to use the "original set of bits" that were associated with that name. New opens happen to the new "set of bits". The space on the disk that the "original bits" are in won't be freed until everybody using that file closes it.

    Anyway, unlink() can do things that you can't do from the Windows command line with del. From the command line you will see something like "file is use" and del will fail. This won't happen with unlink() even on Windows! I suspect that your permissions are wrong or some such thing and that checking the status return will show something.

Re: Deleting a File in Windows
by John M. Dlugosz (Monsignor) on May 05, 2009 at 17:05 UTC
    Try deleting it from the command line, and examine the exit code. If that doesn't work, the trouble isn't Perl. Maybe it is open, read-only, etc.

    —John