Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   open files. (http://www.velocityreviews.com/forums/t894536-open-files.html)

BeHealthy@gmail.com 10-04-2005 05:41 PM

open files.
 
If I use open(fp, $FILENAME), where $FILENAME contains some
subdirectory that hasn't been set up yet, then it fails. Is there any
way I can get around this by letting the program to create the
subdirectory if needed?


Paul Lalli 10-04-2005 05:49 PM

Re: open files.
 
BeHealthy@gmail.com wrote:
> If I use open(fp, $FILENAME), where $FILENAME contains some
> subdirectory that hasn't been set up yet, then it fails.


open() is not used for directories, it is used for files.
perhaps you're thinking of 'opendir()'?

> Is there any
> way I can get around this by letting the program to create the
> subdirectory if needed?


Your algorithm needs some rethinking. You're opening a directory. If
you want to use an analogy to opening files, you're opening the
directory "for reading". There is no such thing as opening a directory
"for writing". If the directory doesn't exist, even if there were a
built-in way to make open auto-create the directory, it would be
created empty. You would then have nothing to read from it.

It's time for you to tell us what you're *actually* trying to
accomplish, rather than ask for help with the method you've already
decided to use to accomplish this unknown goal.

FWIW, I don't see any particular reason you can't just do:
-d $directory_name or mkdir $directory_name
or die "Couldn't create directory $directory_name: $!\n";

(with the possible exception of the chance of a race condition)

Paul Lalli


Babacio 10-04-2005 06:38 PM

Re: open files.
 
"Paul Lalli"

> BeHealthy@gmail.com wrote:
>> If I use open(fp, $FILENAME), where $FILENAME contains some
>> subdirectory that hasn't been set up yet, then it fails.

>
> open() is not used for directories, it is used for files.
> perhaps you're thinking of 'opendir()'?


I think that what the OP means is that $filename =
'/tmp/nonexists/file.txt', for example, and he wants write in it; so
if the file does not exists, the file should be created, but of course
this does not work if the directory '/tmp/nonexists/' does not exist.

May be there is something on CPAN to do that, but it's not a very
difficult thing to write anyway.
--
Bé erre hue ixe eu elle, Bruxelles.

Paul Lalli 10-04-2005 06:57 PM

Re: open files.
 
Babacio wrote:
> Note: The author of this message requested that it not be archived. This
> message will be removed from Groups in 6 days (Oct 11, 2:38 pm).


Please don't do that. It's rude.

> "Paul Lalli"
>
> > BeHealthy@gmail.com wrote:
> >> If I use open(fp, $FILENAME), where $FILENAME contains some
> >> subdirectory that hasn't been set up yet, then it fails.

> >
> > open() is not used for directories, it is used for files.
> > perhaps you're thinking of 'opendir()'?

>
> I think that what the OP means is that $filename =
> '/tmp/nonexists/file.txt', for example, and he wants write in it; so
> if the file does not exists, the file should be created, but of course
> this does not work if the directory '/tmp/nonexists/' does not exist.


Hrm. I can see that interpretation.

> May be there is something on CPAN to do that, but it's not a very
> difficult thing to write anyway.


I don't know if there's a module on CPAN to do exactly that, but as you
say, it's not overly difficult to write a subroutine that will do it,
especially if we take advantage of a certain module that does exist:

#!/usr/bin/perl
use strict;
use warnings;
use File::Spec;

sub open_or_make(\$$){
my ($fh_ref, $path) = @_;
my ($v, $dirs, $file) = File::Spec->splitpath($path);
my @dirs = File::Spec->splitdir($dirs);
my $dir;
while (my $curdir = shift @dirs){
$dir = $dir ? File::Spec->catdir($dir, $curdir) : $curdir;
-d $dir or mkdir $dir or return undef;
}
open $$fh_ref, '>', $path or return undef;
return 1;
}

my $filename = 'temp/nothere/subdir/file.txt';
open_or_make my $ofh, $filename
or die "Could not open or make $filename: $!\n";
print $ofh "Hello World\n";
close $ofh;
__END__

Paul Lalli


Babacio 10-04-2005 07:13 PM

Re: open files.
 
"Paul Lalli"

>> Note: The author of this message requested that it not be archived. This
>> message will be removed from Groups in 6 days (Oct 11, 2:38 pm).

>
> Please don't do that. It's rude.


Mmmh, I have my own opinion on this subject, sorry.
But I may make an exception for this group, in fact.
I'll think of it.

> I don't know if there's a module on CPAN to do exactly that, but as
> you say, it's not overly difficult to write a subroutine that will
> do it,


I did not try, because I knew that you were going to do that in just a
blink. You're darn too fast!

> especially if we take advantage of a certain module that does exist:
>
> #!/usr/bin/perl
> use strict;
> use warnings;
> use File::Spec;


Well, stupidely enough, I knew File::Basename but not File::Spec. It
seems quite more complete.

> sub open_or_make(\$$){
> my ($fh_ref, $path) = @_;
> my ($v, $dirs, $file) = File::Spec->splitpath($path);
> my @dirs = File::Spec->splitdir($dirs);
> my $dir;
> while (my $curdir = shift @dirs){
> $dir = $dir ? File::Spec->catdir($dir, $curdir) : $curdir;


Both tricky and elegant.

> -d $dir or mkdir $dir or return undef;
> }
> open $$fh_ref, '>', $path or return undef;
> return 1;
> }
>
> my $filename = 'temp/nothere/subdir/file.txt';
> open_or_make my $ofh, $filename
> or die "Could not open or make $filename: $!\n";
> print $ofh "Hello World\n";
> close $ofh;
> __END__
>
> Paul Lalli


Bravo.
--
Bé erre hue ixe eu elle, Bruxelles.

Paul Lalli 10-04-2005 07:15 PM

Re: open files.
 
Babacio wrote:
> "Paul Lalli"
>
> >> Note: The author of this message requested that it not be archived. This
> >> message will be removed from Groups in 6 days (Oct 11, 2:38 pm).

> >
> > Please don't do that. It's rude.

>
> Mmmh, I have my own opinion on this subject, sorry.


Don't apologize. You're entitled to your opinion. Just as I'm
entitled to add you to my kill file until what I perceive as your
rudeness has ended.

Fare thee well.


Babacio 10-04-2005 07:26 PM

Re: open files.
 
"Paul Lalli"

>> >> Note: The author of this message requested that it not be archived. This
>> >> message will be removed from Groups in 6 days (Oct 11, 2:38 pm).
>> >
>> > Please don't do that. It's rude.

>>
>> Mmmh, I have my own opinion on this subject, sorry.

>
> Don't apologize. You're entitled to your opinion. Just as I'm
> entitled to add you to my kill file until what I perceive as your
> rudeness has ended.


Of course, no problem for me.

--
Bé erre hue ixe eu elle, Bruxelles.

Brian McCauley 10-04-2005 07:39 PM

Re: open files.
 
Paul Lalli wrote:

> my @dirs = File::Spec->splitdir($dirs);
> my $dir;
> while (my $curdir = shift @dirs){
> $dir = $dir ? File::Spec->catdir($dir, $curdir) : $curdir;
> -d $dir or mkdir $dir or return undef;
> }


I think File::Path may help to simplify the above.


Paul Lalli 10-04-2005 07:48 PM

Re: open files.
 
Brian McCauley wrote:
> Paul Lalli wrote:
>
> > my @dirs = File::Spec->splitdir($dirs);
> > my $dir;
> > while (my $curdir = shift @dirs){
> > $dir = $dir ? File::Spec->catdir($dir, $curdir) : $curdir;
> > -d $dir or mkdir $dir or return undef;
> > }

>
> I think File::Path may help to simplify the above.


Whoa. Indeed it would. Why didn't I know about this module?

Many thanks, Brian.

Paul Lalli


Joe Smith 10-05-2005 10:45 AM

Parents of files to be opened
 
BeHealthy@gmail.com wrote:
> If I use open(fp, $FILENAME), where $FILENAME contains some
> subdirectory that hasn't been set up yet, then it fails. Is there any
> way I can get around this by letting the program to create the
> subdirectory if needed?


If you are opening a file for output, you should have said so.

Just get the directory part of $FILENAME and then recursively
(or iteratively) create the parent directory if needed.
-Joe


sub mkdir_p { # Like 'mkdir -p', create parent if needed
my($parent,$success);
foreach my $dir (split '/',$_[0]) {
$parent .= $dir;
next if $parent eq '' or -d $parent;
($success = mkdir $parent,0777) or
(warn "mkdir('$parent') failed: $!\n" and return 0);
} continue {
$parent .= '/';
}
$success; # True if dir needed to be created and was created
}

....
my $newname = "$dst/$name";
my ($dir) = $newname =~ m{(.*)/};
print "mkdir $dir\n" if mkdir_p $dir and $verbose;
open my $fh,'>',$newname or die "...";



All times are GMT. The time now is 07:09 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.