Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem parsing a CSV file

Status
Not open for further replies.

Haazi2

Programmer
Aug 25, 2000
51
US
I accidently placed this as a reply to another post and in the C forum.

I have a function which parses a CSV file then extracts records from that file and writes those records to another file. I pass references to the file handles to this function( a reference to $INFILE and $OUTFILE). When the function attempts to parse the CSV file I get the following parse error message: parse failed: No such file or directory. I am able to parse 2 other CSV files but this one particular generates this error message. Does anyone have any ideas on what could cause this parse error? Thanks
in advance for any help offered.

Here's the code:

In the main section:
my $INFILE = "/temp/info.txt";
my $OUTFILE = "/temp/master.txt";

open(IFILE, "$INFILE") || die "Can\'t open input file\n";
open(OFILE, "$OUTFILE") || die "Can\'t open output file\n";

# pass file handle references to function
writeToMasterFile(\*IFILE, \*OFILE);


# function
sub writeToMasterFile
{
my ($f1, $f2) = @_;

if ( -r $f1 )
{
print "File: $f1 exists and is readable\n";
}
else
{
print "File: $f1 does not exist and/or is not readable\n";
}

while (<$f1>)
{
chomp;
my $csv2 = Text::CSV_XS->new;
print &quot;$_\n&quot;;
if ( $csv2->parse($_))
{
my @mail_entry = $csv2->fields;
my($accttype, $fname, $mname, $lname, $email, $pphone, $bphone, $address, $city, $state, $pcode, $province, $country, $comments, $refcocust, $refcoacct, $branch, $date, $time) = @mail_entry;
#print &quot;\$date = $date\n\n&quot;;
#print &quot;\$time = $time\n\n&quot;;
($hr, $min, $sec) = split /:/, $time;
($mon, $day, $yr) = split /-/, $date;

#print &quot;\$hr = &quot;, $hr, &quot;\n&quot;;
#print &quot;\$min = &quot;, $min, &quot;\n&quot;;
#print &quot;\$sec = &quot;, $sec, &quot;\n\n&quot;;

#print &quot;\$mon = &quot;, $mon, &quot;\n&quot;;
#print &quot;\$day = &quot;, $day, &quot;\n&quot;;
#print &quot;\$yr = &quot;, $yr, &quot;\n\n&quot;;

if ( $mon == $ymon && $day == $yday && $yr == $yyr )
{

if ( $hr >= 12 )
{
print $f2 $_, &quot;\n&quot;;
}
elsif ( $mon == $tmon && $day == $tday && $yr == $tyr )
{
if ( $hr < 12 )
{
print $f2 $_, &quot;\n&quot;;
}
}
}

}
else
{
bail(&quot;parse() failed: $!\n&quot;);
}
}

}



 
If I were you, I would just pass the filename variables to the function and let it do the open() call, instead of passing the filehandles after they're already open. I've had trouble in the past doing this by tring to pass an open error log file, so I just pass either the filename or an array to write to, and do the opening inside the function. Maybe that will help.

Mike B.
 
I posted a reply to this message in the C Forum which might shed some light.

Basically what I recommend is verifying that you have the correct permissions on the file. With certain permissions, the *nix environment will respond that there is no such file even if there is, because the user that the script is running as does not have permission to know that file exists.

Are both CSV files in the same directory?

If you are running the script from the web via apache, you will need to make sure the user 'nobody' or 'httpd' has permission to read the file, depending on your implementation.


Regards,
Gerald
 
Gerald, to answer your questions.

I retrieve 3 CSV files from 3 different servers on a farm. We are using Sun OS v5.7. This script runs as a cron job on a server that is not on the farm. The CSV files are obtained via FTP. All the CSV files end up in the same directory on the server which runs the script as a cron job. I will check the file permissions on the CSV file that gives me trouble.
 
Something does not quite add up here...

Just for kicks and giggles, why dont you change:
open(OFILE, &quot;$OUTFILE&quot;) || die &quot;Can\'t open output file\n&quot;;

to

open(OFILE, &quot;>$OUTFILE&quot;) || die &quot;Can\'t open output file\n&quot;;
^ specifying that the file is opened to be written to...

Dont know about what is going on in your system, but in mine if I try to write to a file that was opened the way you opened $OUTFILE, I get a Bad file descriptor error...

Does /temp/master.txt already exist before you open it or are you trying to create the file?


Regards,
Gerald

 
Gerald

Sorry, $OUTFILE was supposed to be opened for writing. The master.txt file may exist before being written to. It is opened for appending records. It may contain records already.
 
I would try doing 2 things.

First, before I use the open commands, I would test the filename with -e
if (-e $INFILE)

And immediately after each open statement I would print the value of $! and see where it is originating from.

The error that you are getting is not coming from the parse command, because it really doesnt know anything about files it just works with strings.

Whats happening is, it is trying to parse, but since the file cannot be found, open or read it is not getting any good strings to work with so it fails, but does not set $! to an error because it is not programmed that way. So parse is failing, and then you print out the value of $! which was more than likely set earlier by one of the open statements.

also remember that all filenames are case sensitive (except on windoze... tsk tsk :( )

Also I suppose it is possible that the No such file or directory error is entirely unrelated.

Try printing out the value of $csv2->error_input after the parse fails. This is normally set to the argument which parse could not handle when it crashes.

Regards,
Gerald


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top