2009-08-25 6 views

Odpowiedz

23

Można użyć File::Basename i File::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 

I nie dodawać żadnych testów w celu sprawdzenia, czy plik już istnieje, ale to dość łatwo dodać z Perl.

+0

Chyba masz na myśli, a nie '' mkpath' make_path'? W przeciwnym razie dobra odpowiedź. – hobbs

+2

@Hobbs: sprawdź dokumentację dla 'File :: Path'. 'mkpath' jest opisany jako" starsza wersja ", a nowy interfejs używa' make_path' dla tej funkcji. – Telemachus

+1

Ah, to ostatnia zmiana. Wersja, którą mam, nie ma tego interfejsu. :) – hobbs

3

Zastosowanie 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

Nie sądzę, istnieje standardowa funkcja, która może zrobić wszystko, o co prosisz, bezpośrednio z pliku.

Ale mkpath(), z modułu File :: Path, może prawie to zrobić, podając katalog nazwy pliku. Od docs File :: Ścieżka:

Funkcja „mkpath” zapewnia wygodny sposób tworzyć katalogi, nawet jeśli „mkdir” wywołanie jądro nie utworzy więcej niż jeden poziom w katalogu czas.

Zauważ, że mkpath() nie zgłasza błędów w miły sposób: z jakiegoś powodu umiera zamiast tylko zwracać zero.

Biorąc pod uwagę to wszystko, można zrobić coś takiego:

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

Podstawowy kod ma około dwóch dekad, a od tego czasu mody programistyczne bardzo się zmieniły. Korzystasz ze starego stylu File :: Path interface. Nowy interfejs umożliwia wychwycenie wszystkich błędów i radzenie sobie z nimi (lub ignorowanie ich) w zależności od potrzeb. – dland

+0

Dobrze wiedzieć, że istnieje nowy interfejs. Jestem przyzwyczajony do pisania przenośnego Perla, który działa na stare wersje i na różne systemy operacyjne (stąd, na dwóch argach open()), więc zwykle nie dokuczam sobie, ucząc się, co nowego w Perlu. :-) –

+1

@Michael: Rozumiem, że być może będziesz musiał napisać stary Perl z jakichkolwiek powodów, ale nie rozumiem, dlaczego wysłałeś taki kod jako przykład dla innych. Jeśli wiesz o trzyargumentowej formie 'otwartej', użyj go tutaj. Nie potrzebujemy więcej przykładów w sieci dwuargumentowej; mamy już wystarczająco dużo. – Telemachus