2009-08-25 106 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

相關問題