open and read text file

C

cerr

Hi There,

I'm just trying to open a text file and print line by line.
My Code:
my $HANDLE = $filename;
open(HANDLE) or die("Could not open GPS source file.");

foreach $line (<HANDLE>) {
print $line;
print $client $line;

sleep(1);
}
close(HANDLE);
My Problem:
The script keeps dying on open(). :(
The pernmissions of the file are set to -rw-r--r--
So what is the problem here? Not getting it...

Thanks,
Ron
 
J

John Bokma

cerr said:
Hi There,

I'm just trying to open a text file and print line by line.
My Code:
my $HANDLE = $filename;
open(HANDLE) or die("Could not open GPS source file.");

open my $fh, '<', $filename
or die "Can't open '$filename' for reading: $!";
^^^^ ^^^^^^^^^ ^^^^^^^ ^^

Make sure to always add all four items marked with ^

foreach $line (<HANDLE>) {
print $line;
print $client $line;

while ( my $line = <$fh> ) {

print $line;
print $client $line;
sleep(1);
why?

}
close(HANDLE);

I also check close, i.e.

close $fh or die "Can't close '$filename' after reading: $!";
^^^^^ ^^^^^^^^^ ^^^^^^^ ^^

Notice again those four items.
 
M

Martijn Lievaart

Hi There,

I'm just trying to open a text file and print line by line. My Code:
my $HANDLE = $filename;
open(HANDLE) or die("Could not open GPS source file.");

my $handle;
open($handle, "<", $filename) or die("Could not open GPS source file:
$!");
foreach $line (<HANDLE>) {
for my $line (<$handle) {
print $line;
print $client $line;

sleep(1);

Why the sleep?????



HTH,
M4
 
C

cerr

my $handle;
open($handle, "<", $filename) or die("Could not open GPS source file:
$!");


for my $line (<$handle) {



Why the sleep?????

Because i wannt print one line per second only ;)

Thanks Martjin and John, I got it going now!!!
 
J

Jens Thoms Toerring

cerr said:
I'm just trying to open a text file and print line by line.
My Code:
my $HANDLE = $filename;
open(HANDLE) or die("Could not open GPS source file.");
foreach $line (<HANDLE>) {
print $line;
print $client $line;

sleep(1);
}
close(HANDLE);
My Problem:
The script keeps dying on open(). :(
The pernmissions of the file are set to -rw-r--r--
So what is the problem here? Not getting it...

Because your use of open() is completely broken. No kind of
open() function I have ever seen (as far as I remember) works
like that. All take a file name and return a handle that in
subsequent calls of functions to read from or write to the
file etc. is used. A handle is something very different from
the file's name (with the UNIX open() function it's an integer,
with C's fopen() function it's a pointer to some structure)
- and in Perl it's something you don't need to worry about;-)
And open() functions typically also take at least one more
argument that tells for what purpose the file is to be opened
for (i.e. for reading, writing or both - that makes a lot of a
difference when you have e.g. permission to read from but not
to write to the file) etc. And sometimes even additional flags
can or have to be given.

If you want a file opened for reading do

open my $handle, '<', $filename or die "Can't open file\n";
while ( my $line = <$handle> ) { ... }
close $handle;

The first argument to open() is the variable that, after a
successful call of open(), contains the handle for the file.
The second, '<', tells that you want it to be opened for
reading (use '>' for writing, but there are a number of
further possibilities, see 'perldoc -f open' for all the
gory details). And the third is the file name (or, with
other second arguments, it could be a program that then
gets run and from which you want to read its output or to
which you want to send data).

BTW, if I remember correctly, the difference between

for my $line ( <> ) { ... }

and

while ( my $line = <> ) { ... }

is that with 'for' the '<>' is used in list context, so the
whole file has to be read in immediately and thus stored in
memory as a whole. This normally doesn't make much sense.
With 'while' it gets read in line by line instead, so only
a single line has to be kept in memory.

Regards, Jens
 
J

Jens Thoms Toerring

Ben Morrow said:
Quoth (e-mail address removed) (Jens Thoms Toerring):
It's a Perl 4ism that is never used nowadays, but still documented and
supported. A bare
open HANDLE;

Uuups, that's from before my time with Perl. And do I feel lucky;-)
takes the filename from the global $HANDLE in the current package. In
the OP's case it's failing because he sets a lexical $HANDLE instead of
a global.
open doesn't return a filehandle (though some things would be more
convenient if it did). It opens an existing filehandle, auto-vivifying
it if necessary. (It is perfectly OK to pass an already-open filehandle
to open, and it will close it first.)

Mmmm, what means auto-vivifying in this context? And what "opens an
existing file handle"? Obviously, not understanding enough I just see
a variable, not an "existing file handle". Since I can't remember you
being wrong on such things I guess there's some kind of magic going on
I didn't grok yet, so a bit more of explanation would be great!

And I also didn't know about a file getting closed automatically when
the file handle is re-used. What happens when you do e.g.

open my $h1, '<', 'filename1.txt';
my $h2 = $h1;
open $h1, '<', 'filename2.txt';

Does that close the first file or does it stay open because of
'$h2' still refering to it?
Best regards, Jens
 
J

John Bokma

open my $handle, '<', $filename or die "Can't open file\n";

To me the acceptable minimum for the rhs of or would be:

die "Can't open '$filename': $!";

this reports and the filename and why it couldn't be opened.


Personally I prefer to add "for reading" since I consider it more clear
compared to just "Can't open".
 
U

Uri Guttman

JTT> Uuups, that's from before my time with Perl. And do I feel lucky;-)

and it still is supported. nasty old concept. it is used in golfing
sometimes.

JTT> Mmmm, what means auto-vivifying in this context? And what "opens an
JTT> existing file handle"? Obviously, not understanding enough I just see
JTT> a variable, not an "existing file handle". Since I can't remember you
JTT> being wrong on such things I guess there's some kind of magic going on
JTT> I didn't grok yet, so a bit more of explanation would be great!

open my $handle will autovivify a handle in the scalar if it was
undef. same as $ref->{foo} will do if $ref is undef. it used to be you
had to have a typeglob or ref to one in the variable so open would
work. the better lazy way is for perl to do it for you.

JTT> And I also didn't know about a file getting closed automatically when
JTT> the file handle is re-used. What happens when you do e.g.

JTT> open my $h1, '<', 'filename1.txt';
JTT> my $h2 = $h1;
JTT> open $h1, '<', 'filename2.txt';

JTT> Does that close the first file or does it stay open because of
JTT> '$h2' still refering to it?

the handle isn't really in the scalar, but is refered to by the scalar
(the handle is actually a typeglob entry). the file itself will be
closed as will the handle itself. the extra copy now refers to a closed
file and will spit out an error if used for i/o.

uri
 
J

Jürgen Exner

cerr said:
I'm just trying to open a text file and print line by line.
My Code:
my $HANDLE = $filename;
open(HANDLE) or die("Could not open GPS source file.");

This style is an anachronism from the dark ages, supported only for
backward compatibility of ancient code.

Today you should use the three-argument form of open() with a lexical
file handle
open ($Handle, '<', $filename)
and in the error message I would at least include the filename and the
reason why the error occured:
or die ("Couldn't open GPS source file '$filename': $!";)

jue
 
J

John Bokma

Ben Morrow said:
I think I'll take this opportunity to recommend 'autodie' again.

~% perl -Mautodie -e'open my $X, "<", "/not/there"'
Can't open '/not/there' for reading: 'No such file or directory' at
-e line 1
~%

No thought required :).

Yup, I am aware of autodie I just have to start using it. Any chance it
will be a core module in the near feature (as it replaces Fatal)?
 
J

John Bokma

Ben Morrow said:
~% corelist autodie

autodie was first released with perl 5.010001
~%

Ben

john@ecce:~$ perl -Mautodie -e1
Can't locate autodie.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .).
BEGIN failed--compilation aborted.
john@ecce:~$ corelist autodie

autodie was not in CORE (or so I think)
john@ecce:~$
 
J

John Bokma

Ben Morrow said:
The version of Module::CoreList shipped with 5.10.0 only knows about
modules that went in before 5.10.0 shipped. You need 5.10.1.

Ah, shoot. I read 5.010001 as a very, very old Perl 5.0000x version, not
as 5.10.1

Anyway, thanks. I want to switch to autodie in all my (new) scripts for
some time, and have now no more excuses not to.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top