Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Re^4: Rename unreliable on Windows

by elef (Friar)
on Apr 04, 2012 at 11:44 UTC ( #963423=note: print w/replies, xml ) Need Help??

in reply to Re^3: Rename unreliable on Windows
in thread Rename unreliable on Windows

Thanks for that one!
It was indeed my backup sw (WD anywhere backup). After disabling it, the test script runs to 10000 loops without errors.

Followup question: why does this happen and is there an easy workaround (apart from disabling the backup sw)? I mean, I don't think I've had problems with deleting or modifying files, only renaming... And I don't think I've had issues outside of perl.

Replies are listed 'Best First'.
Re^5: Rename unreliable on Windows
by Corion (Pope) on Apr 04, 2012 at 11:53 UTC

    This is how Windows as an operating system works. A file cannot be renamed while it is held open.

    A good backup software would request the backup privilege, and use the Windows Backup API. But even then, I'm not sure whether that would allow renaming a file while it is held open.

      elef should file a bug report / complaint against this backup software. It doesn't even have to use the Backup API. It can simply specify full sharing when opening the file. Simply add in the FILE_SHARE_DELETE bit (which also allows renaming) when opening the file (though, the Backup API likely provides other benefits).

      - tye        

Re^5: Rename unreliable on Windows
by tobyink (Abbot) on Apr 04, 2012 at 12:06 UTC

    is there an easy workaround (apart from disabling the backup sw)?

    You could just keep trying to rename it...

    1 until rename $file1, $file2;

    Of course, if a file can genuinely never be renamed, this will cause your script to keep trying forever. Better to limit to a finite number of attempts at renaming.

    my $attempts; while (not rename $file1, $file2) { $attempts++; die "Could not rename file: $!" if $attempts > 7; sleep $attempts; }
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      You could also throw it into a queue of items "to deal with later".


      Thanks. Hoping that copying is more robust than renaming, I tried this:
      unlink "rename2.txt" or die "Can't delete file: $!"; copy ("rename1.txt", "rename2.txt") or die "Can't copy file: $!"; unlink "rename1.txt" or die "Can't delete file: $!";

      Errors became less frequent, but they're still there. I'll try your suggestion. I really like the idea of sleeping increasing intervals between attempts, too.

      Edit: did the test, and the solution works. I also added some reporting to see how many extra attempts are needed for the renamings to succeed. The second attempt was sufficient every time, and it was needed ~50 times before the script got to 10000 loops. I'll implement this with 5 attempts max (just in case the backup sw spends more time on larger files) and forget about the issue. Thanks.
Re^5: Rename unreliable on Windows
by Sinistral (Prior) on Apr 04, 2012 at 13:28 UTC

    One of the solutions that you could use in conjunction with your script is Unlocker. Although the screen shots highlight the GUI, there's also a command line version. If you used that, your script should then be able to do the rename.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://963423]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2018-06-18 06:15 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (108 votes). Check out past polls.