http://www.perlmonks.org?node_id=1012654

Dr Manhattan has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks

When I open a file within a directory, does a copy of that file have to be located in the same directory as where my perl script is stored?

Because when I don't have a copy of the file where the script is stored, cmd returns the filename along with "No such file or directory" error.

I want to be able to open any file in any directory without it having to be stored in the same place as my perl script

Replies are listed 'Best First'.
Re: Correct pathway to a file
by tobyink (Canon) on Jan 10, 2013 at 13:13 UTC

    No, they don't need to be in the same directory. Just use the full path to the file when opening it...

    open my $fh, '<', '/home/tai/Documents/foo.txt'; while (my $line = <$fh>) { print "Got line: $line"; } close $fh;
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Correct pathway to a file
by johngg (Canon) on Jan 10, 2013 at 14:12 UTC

    Prepend your directory name to the filename so as to give the path to the file, in your case an absolute path so it wouldn't matter where your script was. If you are using a relative path for your directory then that must be the path to the directory from where your script is running or you must do a chdir in your script to the place from where that relative path would succeed.

    Here is a trivial example.

    $ ls test/dir1/ fileA fileB $ head -99 test/dir1/file* ==> test/dir1/fileA <== fileA - line 1 fileA - line 2 ==> test/dir1/fileB <== fileB - line 1 fileB - line 2 fileB - line 3

    This script, run from the parent directory of "test"

    use strict; use warnings; use 5.010; my $dir = q{test/dir1}; opendir my $dirHandle, $dir or die qq{opendir: $dir: $!\n}; while ( my $file = readdir $dirHandle ) { next unless -f qq{$dir/$file}; say qq{*** $file ***}; print do { open my $fh, q{<}, qq{$dir/$file} or die qq{open: < $dir/$file: $!\n}; <$fh>; }; }

    Gives this output

    *** fileA *** fileA - line 1 fileA - line 2 *** fileB *** fileB - line 1 fileB - line 2 fileB - line 3

    I hope this is helpful.

    Cheers,

    JohnGG

Re: Correct pathway to a file
by vinoth.ree (Monsignor) on Jan 10, 2013 at 13:13 UTC

    Why are you creating separate nodes for the single problem? You would have asked the same in you previous node

    No such file or directory error
    Open a folder

    Even I can see all you nodes are all related to a single question!

Re: Correct pathway to a file
by blue_cowdawg (Monsignor) on Jan 10, 2013 at 15:00 UTC

    Dear Monk,
    Are you actually reading the replies you get or are you causing me to waste my time? If you actually read my replies to your previous posting on this subject you'd have the answer.

    Does this ring a bell?

    sub countWords { # Path and filename are passed to this sub. Join the two for the fu +lly # qualified path name. my $fname=join("/",@_); open FIN,"< $fname" or die "$fname:$!"; my @lines=<FIN>; chomp @lines; close FIN; my $count=0; foreach my $line(@lines){ map { $count++ } split (/[\s\t\n]+/,$line); } printf "There are %d words in %s\n",$count,$fname; }


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg

      Hi blue cowdawg

      I tried this within the sub

      my $fname = join("/",$_[0]); my $INP = $_[1]; open (FIN, "<$fname") or die "$fname$!"; my @words =<FIN>; chomp @words; close FIN;

      because I sent my sub the file+directory like you showed, and also an integer which has to be used later in the sub.

      But even the short script you sent earlier only works if I have copies of the text file at the directory where I specify and also where my perl script is stored.

            because I sent my sub the file+directory like you showed, and also an integer which has to be used later in the sub.

        OK: let me spell something out here... Peruse the following code and I'm going to add line numbers so I can point to specific lines in my follow up explaination.

        1. sub processFile { 2. my ($dir,$node,$someNumber)=@_; | | handwaving. }
        First let me comment that the array @_ contains all arguments passed to the sub. The code I just supplied is the equivalent to:
        1, sub processFile { 2. my $dir=shift; #@_ is implied! 3. my $node=shift; 4, my $someNumber=shift;
        I'm not sure what you thought you were accomplishing by referencing $_[0] given that refers to the scalar in the array with the lowest index. You needed $_[0] to have a "/" and $_[1] concatenated.

        When you are given answers to your questions here on PM please take the time not only to fully read the answer but take the trouble of actually learning what the answer means.


        Peter L. Berghold -- Unix Professional
        Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Correct pathway to a file
by Anonymous Monk on Jan 11, 2013 at 02:40 UTC

    I want to be able to open any file in any directory without it having to be stored in the same place as my perl script

    use absolute paths, use File::Find::Rule , use File::Spec->rel2abs

    But I've said all this before