Reputation: 5553
I have a Perl script that works on Windows XP.
It uses File::Copy's move
function to move a directory tree to another place on the same drive. The script fails (silently) on Windows 2008. Nothing moved, nothing deleted.
I am using ActiveState Perl 5.10.0 Build 1005 and the File::Copy that comes with it.
Anyone know of issues with ActiveState Perl on Windows 2008 that might cause this?
Example script:
use File::Copy;
print "Move AAA to ZZZ\n";
move("AAA", "ZZZ");
print "Done.\n";
Upvotes: 4
Views: 9411
Reputation: 76
I too was finding move() and unlink() were failing on files that were created within the last 10 seconds. I added a call to 'sleep 10' before move() and it now works! Strange but true.
I then found http://answers.microsoft.com/en-us/windows/forum/windows_7-files/windows-7-does-not-refresh-folder-views/9d1ede23-2666-4951-b3b9-b6c1ce3d1ebf?page=23 which led me to adding...
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters
FileInfoCacheLifetime
FileNotFoundCacheLifetime
DirectoryCacheLifetime
as DWORD's set to 0... and now it works without the pause. Can't vouch for potential server performance impact though.
This seems like crazy default behaviour to me, and it's not restricted to Perl!
Also see Windows file share: why sometimes newly created files aren't visible for some period of time?
Upvotes: 0
Reputation: 16321
I just encountered this myself, and in my particular situation, despite the exact same error ("No such file..."), it was actually that I had a file, from deep within the hierarchy I was renaming, open in a text editor somewhere. As soon as I closed that file, the error stopped occurring.
Upvotes: 2
Reputation: 5553
Rather than slog through another half dozen Perl modules looking for one that did what I wanted, I adopted a hybrid approach and called out to DOS to use the "move" command. DOS move has its own peculiarities. For example, if you copy c:\temp\AAA to c:\temp\BBB and BBB exists already, you get c:\temp\BBB\AAA. But if BBB does not already exist, you get c:\temp\BBB, with no AAA underneath it. To avoid that, I first create BBB (if it does not exist) and then delete it. This causes all the directories down to BBB to be created if absent.
Here is my code:
sub move($$) {
my ($source, $target) = @_;
if (! -d $source) {
print " ERROR: Source directory does not exist: $source. Not copying to $target.\n";
}
elsif (-d $target) {
print " ERROR: Target directory already exists: $target. Not copying from $source.\n";
}
else {
$source =~ s|/|\\|g;
$target =~ s|/|\\|g;
my $results = `if not exist "$target" mkdir "$target" & rmdir "$target" & move /Y "$source" "$target"`;
print " Results of move \"$source\" \"$target\":\n $results\n";
}
}
Upvotes: 1
Reputation: 3167
I've had weird things happen to me on Windows with moving and removing files. The solution was to use the CPAN module File::Remove.
Upvotes: 1
Reputation: 34120
If you don't want to have to check the return value, you can have autodie
do it for you.
Since move()
and copy()
return a zero to indicate an error, and that's what autodie
assumes, it's fairly straight forward.
use strict;
use warnings;
use File::Copy;
use autodie qw'copy move';
move("AAA", "ZZZ"); # no need to check for error, because of autodie
print "Done.\n";
Assuming that "AAA
" doesn't exist, here is the output ( on STDERR
).
Can't move('AAA', 'ZZZ'): No such file or directory at test.pl line 7
Upvotes: 8
Reputation: 12695
From the documentation:
RETURN
All functions return 1 on success, 0 on failure. $! will be set if an error was encountered.
The example fails silently because nothing is checking what $! is on failure. Try this:
move($from, $to) || die "Failed to move files: $!";
Upvotes: 12