2009-08-25 53 views
8

如果你有一个文件路径(例如,/home/bob/test/foo.txt),其中路径中的每个子目录可能存在也可能不存在,我怎样才能以某种方式创建文件foo.txt使用“/home/bob/test/foo.txt”作为唯一的输入,而不是在路径中逐个创建每个不存在的目录,最后创建foo.txt本身?如何在Perl中创建一个包含所有子目录的路径?

回答

23

您可以使用File::BasenameFile::Path

use strict; 
use File::Basename; 
use File::Path qw/make_path/; 

my $file = "/home/bob/test/foo.txt"; 
my $dir = dirname($file); 
make_path($dir); 
open my $fh, '>', $file or die "Ouch: $!\n"; # now go do stuff w/file 

我没加任何测试,看看文件已经存在,但是这很容易用Perl补充。

+0

我想你的意思'mkpath',不'make_path'?否则,很好的答案。 – hobbs 2009-08-25 09:49:36

+2

@Hobbs:查看“File :: Path”的文档。 'mkpath'被描述为“遗留”,并且新接口为该功能使用'make_path'。 – Telemachus 2009-08-25 10:38:04

+1

啊,这是最近的一次变化。我的版本没有这个界面。 :) – hobbs 2009-08-26 04:32:16

3

使用make_dir from File::Util

use File::Util; 
    my($f) = File::Util->new(); 
    $f->make_dir('/var/tmp/tempfiles/foo/bar/'); 

    # optionally specify a creation bitmask to be used in directory creations 
    $f->make_dir('/var/tmp/tempfiles/foo/bar/',0755); 
2

我不认为有,可以做所有的你问什么,直接从文件名的标准功能。

但是来自模块File :: Path的mkpath()几乎可以在给定文件名的目录的情况下完成。从文件::路径文档:

的“mkpath”功能提供了一个 便捷的方式来创建目录, 即使你的“MKDIR”内核调用不会 创建于 目录的多个级别一次。

请注意,mkpath()不会以很好的方式报告错误:由于某种原因,它会死亡而不是返回零。

鉴于这一切,你可以这样做:

use File::Basename; 
use File::Path; 

my $fname = "/home/bob/test/foo.txt"; 

eval { 
    local $SIG{'__DIE__'}; # ignore user-defined die handlers 
    mkpath(dirname($fname)); 
}; 
my $fh; 
if ([email protected]) { 
    print STDERR "Error creating dir: [email protected]"; 
} elsif (!open($fh, ">", $fname)) { 
    print STDERR "Error creating file: $!\n"; 
} 
+1

底层代码大约有二十年的历史,编程时尚自那时以来已经发生了很大的变化。您正在使用旧式的File :: Path界面。新的界面可以让你捕捉所有的错误,并在适当的时候处理(或忽略)它们。 – dland 2009-08-25 08:49:39

+0

很高兴知道这里有一个更新的界面。我习惯于编写适用于旧版本和跨操作系统的可移植Perl(因此,这是两个参数open()),所以我通常不会通过学习Perl中的新特性来挑逗自己。 :-) – 2009-08-25 09:11:48

+1

@Michael:据我所知,你可能需要编写旧的Perl出于任何原因,但我不明白为什么你会发布这样的代码作为其他例子。如果您知道“open”的三参数形式,请在此处使用它。我们在两个参数形式的网络上不需要更多的例子;我们已经绰绰有余了。 – Telemachus 2009-08-25 10:41:28

相关问题