Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Read on closed filehandle

Reply
Thread Tools

Read on closed filehandle

 
 
Russ
Guest
Posts: n/a
 
      02-01-2007
I have a very simple script to read an input file, skip everything
between the strings "BEGIN" and "END", and store the results in an
output
file.

----------------------------

3 open(IN,"input.txt");
4 open(OUT,">output.txt");
5
6 while(<IN>) {
7 chomp;
8 if (/BEGIN/) {
9 until (/END/) {
10 $_ = <IN>;
11 }
12 } else {
13 print OUT "$_\n";
14 }
15 }
16
17 close IN;
18 close OUT;

----------------------------------

When I run this on a small file, about 28 kb, it works fine. When I
try it on a large file, about 3 gigs , I get the error:

"Read on closed filehandle <IN> at trim.pl line 6."

The file structure is essentailly the same, the only difference is the
size.
I bump into limits in many text editors when I try to access the large
file, and
I assume that this is a similar limitation in PERL. Is there any way
around this?

I also wouldn't mind some constructive criticism on the script
itself. It seems like there should
be a more elegant way to accomplish this task which might avoid this
problem.
Any suggestions?

Thanks,
Russ

 
Reply With Quote
 
 
 
 
Mark Clements
Guest
Posts: n/a
 
      02-01-2007
Russ wrote:
> I have a very simple script to read an input file, skip everything
> between the strings "BEGIN" and "END", and store the results in an
> output
> file.
>
> ----------------------------
>
> 3 open(IN,"input.txt");
> 4 open(OUT,">output.txt");
> 5
> 6 while(<IN>) {
> 7 chomp;
> 8 if (/BEGIN/) {
> 9 until (/END/) {
> 10 $_ = <IN>;
> 11 }
> 12 } else {
> 13 print OUT "$_\n";
> 14 }
> 15 }
> 16
> 17 close IN;
> 18 close OUT;
>
> ----------------------------------
>
> When I run this on a small file, about 28 kb, it works fine. When I
> try it on a large file, about 3 gigs , I get the error:
>
> "Read on closed filehandle <IN> at trim.pl line 6."


It's best if you post code without the line numbers: makes it easier for
people to run it. You also need to run with

use strict;
use warnings;

and check the return value of your system calls (you need to do this
*always*), eg

open (my $infh,"<","input.txt") or die $!;


That should give you some pointers. perldoc -q open

Also check what

perl -V

reports for uselargefiles.

Mark

 
Reply With Quote
 
 
 
 
jgraber@ti.com
Guest
Posts: n/a
 
      02-01-2007

"Russ" <(E-Mail Removed)> writes:
> I have a very simple script to read an input file, skip everything
> between the strings "BEGIN" and "END", and store the results in an
> output file.


> I also wouldn't mind some constructive criticism on the script
> itself. It seems like there should
> be a more elegant way to accomplish this task which might avoid this
> problem.
> Any suggestions?


Size of input file is not the problem.
What did you want to happen if there is a BEGIN but no END?

# stop printing when see BEGIN, restart when see END
perl -n -e 'print unless /^BEGIN/ .. /^END/' < infile > outfile

--
Joel
 
Reply With Quote
 
Russ
Guest
Posts: n/a
 
      02-01-2007
On Feb 1, 5:40 pm, Mark Clements <(E-Mail Removed)>
wrote:

> use strict;
> use warnings;
>
> and check the return value of your system calls (you need to do this
> *always*), eg
>
> open (my $infh,"<","input.txt") or die $!;
>
> That should give you some pointers. perldoc -q open
>
> Also check what
>
> perl -V
>
> reports for uselargefiles.


I made the changes you suggested. The program dies at the open()
statement with error:

"Value too large for defined data type at trim.pl line 5."

Also, 'perl -V' does not reference uselargefiles. Is that something
that is set when perl in
initially compiled on the system? Does perl need to be recompiled to
set this value?

Thanks,
Russ


 
Reply With Quote
 
jgraber@ti.com
Guest
Posts: n/a
 
      02-01-2007
"Russ" <(E-Mail Removed)> writes:

> I have a very simple script to read an input file, skip everything
> between the strings "BEGIN" and "END", and store the results in an
> output file.
>
> 3 open(IN,"input.txt");
> 4 open(OUT,">output.txt");
> 5
> 6 while(<IN>) {
> 7 chomp;
> 8 if (/BEGIN/) {
> 9 until (/END/) {
> 10 $_ = <IN>;
> 11 }
> 12 } else {
> 13 print OUT "$_\n";
> 14 }
> 15 }
> 16
> 17 close IN;
> 18 close OUT;


> I also wouldn't mind some constructive criticism on the script
> itself.


additional comments to my previous reply
Be sure to use strict; and use warnings;
No use in chomping if you intend to add \n afterwards anyway.
What about anchoring BEGIN and END to front or end or whole line?
What about lines like "In every BEGINNING there is also an ENDING"?
Check for errors when opening and closing files,
since printing to a full disk wont be notied until the close.
close OUT || die "cant close '$outfile' because of error : $!\n";

Add the following lines to the end of your program
and run it as its own input file and then notice that it never exits.
# BEGIN
# eND

What did you want to do in the above case;
omit from BEGIN to eof,
or keep it?

--
Joel
 
Reply With Quote
 
Russ
Guest
Posts: n/a
 
      02-02-2007
On Feb 1, 6:10 pm, "(E-Mail Removed)"
<(E-Mail Removed)> wrote:
> On Feb 1, 2:34 pm, "Russ" <(E-Mail Removed)> wrote:
>
> > I have a very simple script to read an input file, skip everything
> > between the strings "BEGIN" and "END", and store the results in an
> > output
> > file.

>
> > ----------------------------

>
> > 3 open(IN,"input.txt");

>
> Please check the return value of open.
>
> > 4 open(OUT,">output.txt");
> > 5
> > 6 while(<IN>) {
> > 7 chomp;

>
> No need to chomp if you're going to append
> "\n" before printing
>
> > 8 if (/BEGIN/) {
> > 9 until (/END/) {
> > 10 $_ = <IN>;
> > 11 }

>
> What happends if your file
> matches /BEGIN/ but never
> matches /END/?
> You keep reading, even
> after you reach the end
> of the file.
>
>
>
> > 12 } else {
> > 13 print OUT "$_\n";
> > 14 }
> > 15 }
> > 16
> > 17 close IN;
> > 18 close OUT;

>
> > ----------------------------------

>
> > When I run this on a small file, about 28 kb, it works fine. When I
> > try it on a large file, about 3 gigs , I get the error:

>
> > "Read on closed filehandle <IN> at trim.pl line 6."

>
> > The file structure is essentailly the same, the only difference is the
> > size.
> > I bump into limits in many text editors when I try to access the large
> > file, and
> > I assume that this is a similar limitation in PERL. Is there any way
> > around this?

>
> > I also wouldn't mind some constructive criticism on the script
> > itself. It seems like there should
> > be a more elegant way to accomplish this task which might avoid this
> > problem.
> > Any suggestions?

>
> More concise:
>
> while (<IN>) {
> next if /BEGIN/ .. /END/;
> print OUT $_;
>
> }
>
> --
> Hope this helps,
> Steven


Steven,

Thanks for in suggestions. It works fine but I'm not familiar with the
use of '..' in the next statement.
I have used the 'next if' construct with single regular expressions,
is the above code just representing
the entire group of characters between the "BEGIN" and "END" strings?

If that's the case, and I don't have an "END", will the code print
everything between "BEGIN"
and the end of the file?

Thanks,
Russ D.

 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      02-02-2007
Russ <(E-Mail Removed)> wrote:

> read an input file, skip everything
> between the strings "BEGIN" and "END",

^^^^^^^


> It seems like there should
> be a more elegant way to accomplish this task which might avoid this
> problem.



Your Question is Asked Frequently.


> Any suggestions?



perldoc -q between

How can I pull out lines between two patterns that are themselves on dif‐
ferent lines?


--
Tad McClellan SGML consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
Dan Mercer
Guest
Posts: n/a
 
      02-02-2007

"Russ" <(E-Mail Removed)> wrote in message news:(E-Mail Removed) oups.com...
: I have a very simple script to read an input file, skip everything
: between the strings "BEGIN" and "END", and store the results in an
: output
: file.
:
: ----------------------------
:
: 3 open(IN,"input.txt");
: 4 open(OUT,">output.txt");
: 5
: 6 while(<IN>) {
: 7 chomp;
: 8 if (/BEGIN/) {
: 9 until (/END/) {
: 10 $_ = <IN>;

You aren't checking to see if <IN> hits EOF. Undoubtedly,
the last line in the file contains the word "END"

Dan Mercer


: 11 }
: 12 } else {
: 13 print OUT "$_\n";
: 14 }
: 15 }
: 16
: 17 close IN;
: 18 close OUT;
:
: ----------------------------------
:
: When I run this on a small file, about 28 kb, it works fine. When I
: try it on a large file, about 3 gigs , I get the error:
:
: "Read on closed filehandle <IN> at trim.pl line 6."
:
: The file structure is essentailly the same, the only difference is the
: size.
: I bump into limits in many text editors when I try to access the large
: file, and
: I assume that this is a similar limitation in PERL. Is there any way
: around this?
:
: I also wouldn't mind some constructive criticism on the script
: itself. It seems like there should
: be a more elegant way to accomplish this task which might avoid this
: problem.
: Any suggestions?
:
: Thanks,
: Russ
:


 
Reply With Quote
 
Peter J. Holzer
Guest
Posts: n/a
 
      02-02-2007
On 2007-02-01 23:03, Russ <(E-Mail Removed)> wrote:
> Also, 'perl -V' does not reference uselargefiles. Is that something
> that is set when perl in initially compiled on the system? Does perl
> need to be recompiled to set this value?


Yes.

hp


--
_ | Peter J. Holzer | Es ist ganz einfach ihn zu verstehen, wenn
|_|_) | Sysadmin WSR | man nur alle wichtigen Worte im Satz durch
| | | (E-Mail Removed) | andere ersetzt.
__/ | http://www.hjp.at/ | -- Nils Ketelsen in danr
 
Reply With Quote
 
Joe Smith
Guest
Posts: n/a
 
      02-03-2007
(E-Mail Removed) wrote:
> "Russ" <(E-Mail Removed)> writes:
>> I have a very simple script to read an input file, skip everything
>> between the strings "BEGIN" and "END", and store the results in an
>> output file.

>
>> When I run this on a small file, about 28 kb, it works fine. When I
>> try it on a large file, about 3 gigs , I get the error:

>
> Size of input file is not the problem.


No, the size of the input file _is_ the problem.

On a version of perl compiled on a 32-bit machine without "uselargefiles=define",
things like segfault or "read on closed filehandle" will occur after reading
2,147,483,647 bytes from the input file.

-Joe
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
prematurely closed filehandle Jim Perl Misc 9 07-07-2006 04:08 PM
Read from filehandle opened for appending Sisyphus Perl Misc 6 04-05-2006 04:19 AM
What with this open file descriptor/"Read on closed filehandle " stuff? Rex Gustavus Adolphus Perl Misc 17 03-07-2004 01:37 AM
closed filehandle Sam Perl Misc 17 09-15-2003 05:54 PM
Opera - .closed not accessible if window is closed? Matt Kruse Javascript 5 09-09-2003 01:27 AM



Advertisments