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

Good Morning perl Monks!

I have another issue I'm coming across.

I have a need to open a file (Step1_Comments.csv), manipulate the data, then save the data to a new file.
(Step2_comments.csv)
Perl does this easily!

The problem comes in when I go to OPEN the new file (Step2_Comments.csv) in my same perl script. Perl seems to think there is only one line (record) in the file!

I tried using Tie::File instead of OPEN to access the Step2 file. Tie::File gave me this error:

"Empty record separator not supported" by Tie::File

My perl code to open the step2 file works perfectly in a file all by itself. It opens the file, sees all the rows, and closes just fine.
But when that same code is at the end of the script that creates the file in the first place, it doesn't want to see more than one row in the file..... weird huh!?

Any help is appreciated.

I know this was kind of convoluted, let me know if you need further information.

Thank you in Advance! You guys always come through for me!

Replies are listed 'Best First'.
Re: Opening a File Twice
by Corion (Patriarch) on May 28, 2008 at 14:07 UTC

    You're not closing the file from your first step and hence some (or rather, all) lines remain in memory, buffered by Perl or the OS. close the first file or use a lexical filehandle (or both), and you will see the data when you reopen the file.

      I "think" I am closing the filehandle after I create the STEP2 file, but before I access the second time for reading.

      At least I think I am.

      Here is a shortened version of the code:

      ######################## # OPEN THE STEP 1 FILE # ######################## foreach (@files) { chdir($dir1); ## Verify Files exist die "File: $_ does not exist. \n $!" unless -e ; ## Verify Files are read/writable die "File: $_ isn't read or writable \n $!" unless ((-r $_ ) && (-w $_ )); ### Open the file open (FILE, "<", $_ ) or die "Cannot open the file $! \n"; select((select(FILE), $/ = undef)[0]); my @array_contents = <FILE>; close (FILE) or die $!;; ## DO SOME STUFF ########################## # CREATE THE STEP 2 FILE # ########################## chdir($dir2); $outputfile = "STEP2_" . $_; open(OUTFILE, ">" , $outputfile) or die $!; print OUTFILE $contents; close OUTFILE or die $!; }; ########################## # ACCESS THE STEP 2 FILE # ########################## chdir($dir2); open (SFCOMMENTS, "<STEP2_CaseComment.csv") or die "Cannot open Salesf +orce Comments file $! \n"; $count = 0; while (<SFCOMMENTS>) { print "Count is: $count \n"; $count ++; } close SFCOMMENTS or die $!;
        You might want to change
        foreach (@files) {
        to
        foreach my $file (@files) {
        Then you could replace
        $outputfile = "STEP2_" . $_; open(OUTFILE, ">" , $outputfile) or die $!;
        with
        $outputfile = "STEP2_" . $file; open(OUTFILE, ">" , $outputfile) or die "opening $outputfile $!";
        The value of $_ is almost certainly used for more than the name of the file being processed. These changes will guarantee the filename is retained, and associate the actual filename with the error.

        Revise: The foreach was corrected, thanks to moritz kindly pointing out my gaffe.

        With Perl 5.8.5, I can't reproduce your error. I've changed your code around a bit to make it work with strict and removed some of the file tests because they are redundant but still:

        use strict; my @files = qw(CaseComment.csv); my $dir1 = "."; my $dir2 = "."; ######################## # OPEN THE STEP 1 FILE # ######################## foreach (@files) { my $filename = "$dir1/$_"; #chdir($dir1); # replace by "$dir/$_" # Redundant - open() will die with # an informative message anyway ## Verify Files exist #die "File: '$filename' does not exist: $!" # unless -e $filename; ## Verify Files are read/writable #die "File: $filename isn't read or writable \n $!" # unless ((-r $filename ) && (-w $filename )); ### Open the file open (FILE, "<", $filename ) or die "Cannot open the file '$filena +me': $!\n"; #select((select(FILE), $/ = undef)[0]); # what is that for? my @array_contents = <FILE>; close (FILE) or die $!; ## DO SOME STUFF ########################## # CREATE THE STEP 2 FILE # ########################## #chdir($dir2); my $contents = <<TESTCOMMENTS; Line 1 line 2 linE 3 TESTCOMMENTS my $outputfile = "$dir2/STEP2_" . $_; warn "Writing '$contents'"; open(OUTFILE, ">" , $outputfile) or die "Couldn't create '$outputf +ile':$!"; print OUTFILE $contents; close OUTFILE or die $!; }; ########################## # ACCESS THE STEP 2 FILE # ########################## #chdir($dir2); my $commentsfile = "$dir2/STEP2_CaseComment.csv"; open (SFCOMMENTS, "<", $commentsfile) or die "Cannot open Salesforce C +omments file '$commentsfile' : $! \n"; my $count = 0; while (<SFCOMMENTS>) { print "Count is: $count \n"; $count ++; } close SFCOMMENTS or die $!;
        outputs for me:
        C:\Projekte>perl -w tmp.pl Writing 'Line 1 line 2 linE 3 ' at tmp.pl line 44. Count is: 0 Count is: 1 Count is: 2

        Maybe your assignment to $contents is somehow wrong? More debugging information is needed.

        I don't see where your problem has anything to do with the ordering of opens and closes. More likely the records are not getting written correctly. Your code slurps the contents of the input file as one record into the first element of @array_contents then writes $contents out to the second file without any record delimiters. The code provided does nothing when I run it. Have you verified the contents of your written file using a text editor? Can you provide a snippet of code that behaves as you say?

        Two other minor points. You call chdir() inside your foreach(@files) loop. This will only work for absolute path names otherwise the code will try to chdir to a subdirectory from inside a subdirectory. The $count loop displays the first record as a count of 0. While it would be proper to consider this an index of 0, the count should read 1.


        s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}
Re: Opening a File Twice
by ikegami (Patriarch) on May 28, 2008 at 18:25 UTC
    Sounds like $/ is undef.
      Thank you all for your help.
      It turn out that is was a mixture of several factors.

      1) My code sucks, and needed to be cleaned up.
      2) $/ was undef. This HAD to be undef to slurp in the data, but it was still undef when I output the data.
      THAT was why I had only one record output.
      Thanks again!

      You guys rule!