What is the best way in Perl to copy files into a yet-to-be-created directory tree?
34,648
Solution 1
use File::Path;
use File::Copy;
my $path = "tardir/dest1/dest2/";
my $file = "test.txt";
if (! -d $path)
{
my $dirs = eval { mkpath($path) };
die "Failed to create $path: $@\n" unless $dirs;
}
copy($file,$path) or die "Failed to copy $file: $!\n";
Solution 2
use File::Basename qw/dirname/;
use File::Copy;
sub mkdir_recursive {
my $path = shift;
mkdir_recursive(dirname($path)) if not -d dirname($path);
mkdir $path or die "Could not make dir $path: $!" if not -d $path;
return;
}
sub mkdir_and_copy {
my ($from, $to) = @_;
mkdir_recursive(dirname($to));
copy($from, $to) or die "Couldn't copy: $!";
return;
}
Solution 3
File::Copy::Recursive::fcopy() is non-core but combines the File::Path::mkpath() and File::Copy::copy() solution into something even shorter, and preserves permissions unlike File::Copy. It also contains other nifty utility functions.
Solution 4
See the other answers for doing the copying, but for creating the directory Path::Class is very nice to use:
use Path::Class;
my $destination_file = file('tardir/dest1/dest2/test.txt');
$destination_file->dir->mkpath;
# ... do the copying here
Author by
Chandrasekhar
Updated on January 09, 2020Comments
-
Chandrasekhar over 4 years
What is the best way in Perl to copy files to a yet-to-be-created destination directory tree?
Something like
copy("test.txt","tardir/dest1/dest2/text.txt");
won't work since the directory tardir/dest1/dest2 does not yet exist. What is the best way to copy with directory creation in Perl?
-
Michael Carman over 15 yearsAccording to corelist File::Path has been part of the core since 5.001.
-
Leon Timmermans over 15 yearsInteresting. It's not in 5.10, but it is present in earlier versions.
-
Michael Carman over 15 yearsCorelist is a little buggy about the notation for version numbers. Run "corelist -a File::Path" and you'll see that v2.04 was released with perl "5.01" (instead of 5.010).
-
user2522201 over 15 years@Leon, I downvoted you because File::Path is a core module and has been for a while (perldoc.perl.org/index-modules-F.html) and I felt your solution was unnecessarily re-inventing the wheel. Your solution isn't "bad", just not the the best IMHO, I have taken back my vote.
-
Leon Timmermans over 15 yearsCPAN suggests it isn't in the core, but I guess that's "dual living" confusion, mystery solved.
-
dland over 15 yearsI'm the current maintainer of File::Path, it was dual-lifed on CPAN in the run up to 5.10
-
ysth over 15 yearsFile::Path::mkpath throws an exception on error so your "or die" isn't correct.
-
Marco over 12 yearsThis approached proved to be the easiest of the choices available. I opted to use File::Copy::Recursive's dircopy function. The 2 main advantages are that File::Copy::Recursive's functions will automatically make any dir. structure and also will preserve the permissions when it makes copies.