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

I've tried everything and I'm tired of beating my ahead against the wall on this. I'm trying to print the contents of a file to a browser window (you may properly spank me if this is more of a .cgi issue). Here's the code:
open (FILE, 'htmlcal.txt'); print "Content-Type: text/html\n\n"; print "What the f***?"; print <FILE>; close FILE;

The 'What the f***?' prints out nicely but the contents of the file don't show. I've tried replacing  print <FILE>;

with

my @contents = <FILE>; print "@contents";

but to no effect. I'm not getting any errors so what am I doing wrong here?

Replies are listed 'Best First'.
(jeffa) Re: Printing file to browser
by jeffa (Bishop) on Apr 02, 2001 at 23:50 UTC
    Well, if you are getting errors - you won't know unless you check for them:
    open (FILE, 'htmlcal.txt') or die "Hey, there's a problem, bub: $!"

    Jeff

    R-R-R--R-R-R--R-R-R--R-R-R--R-R-R--
    L-L--L-L--L-L--L-L--L-L--L-L--L-L--
    
      Good catch, but I'm still getting no error. The file definitely exists and I've got permissions jacked up to 777 on it.
Re: Printing file to browser
by tune (Curate) on Apr 02, 2001 at 23:51 UTC
    open (FILE, 'htmlcal.txt') or die $!,"\n"; print "Content-Type: text/html\n\n"; print "What the f***?"; while ($line = <FILE>) { print $line; } close FILE;
    will be better...

    -- tune

      Or to be even cleaner (and faster):
      open(FILE, 'htmlcal.txt') or die $!,"\n"; print "Content-type: text/html\n\n"; print "What the f***?"; for(<FILE>) { print; } close(FILE);

      --isotope
      http://www.skylab.org/~isotope/
Re: Printing file to browser
by arturo (Vicar) on Apr 02, 2001 at 23:51 UTC

    I notice there's no "or die" up there on your open. If the open fails, it will do so silently. (and nothing will get printed from a file that ain't open!)

    FWIW, I'd do it this way:

    open (FILE, $filename) or die "Can't open $filename: $!\n"; print $_ while (<FILE>); close FILE;

    HTH.

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Re: Printing file to browser
by damian1301 (Curate) on Apr 02, 2001 at 23:51 UTC
    open(FILE,"file.txt") || die; print while <FILE>; close FILE;
    Should do the trick. You have to print it on a line-by-line basis, which is what the while loop will do.

    UPDATE: You all beat me to it, but mine took less space!! :)

    Almost a Perl hacker.
    Dave AKA damian

    I encourage you to email me

      Well, yes, but a) you didn't explicitly note the problem of not checking the return value of the call to open and b) you're wrong when you say it has to be done line-by-line -- either construct nysus tried should work (and does, on my system =)

      Philosophy can be made out of anything. Or less -- Jerry A. Fodor

        You're right, it doesn't have to be printed line-by-line. But I would recommend it.

        The reason is that if the file is large, then the user will (usually) see what's been read and printed so far (assuming no caching, buffering, etc) if you do it line-by-line, but will have to wait until the whole file is processed if you do it as an array slurp. And, possibly, the connection might time-out durring the slurp if you're not careful.

        Of course, I could be totally mistaken. :-)

        bbfu
        Seasons don't fear The Reaper.
        Nor do the wind, the sun, and the rain.
        We can be like they are.

Re: Printing file to browser
by Daddio (Chaplain) on Apr 03, 2001 at 01:12 UTC
    Two things: are you using the -w flag, and is the file in the location you are expecting?

    When I checked the code, I found that when the file existed in the current directory, I saw the whole thing, but when it didn't, all I saw what what you are seeing.

    With the -w flag set, I got this message back when the file did not exist:

    readline() on closed filehandle main::FILE at script.pl line 7.
Re: Printing file to browser
by nysus (Parson) on Apr 03, 2001 at 01:17 UTC
    I found the problem...thanks to everyone who helped. The problem was tha the 'htmlcal.txt' file I was trying to read from was not properly closed out by a Perl library file that my script called.

    Sorry for the stupidity. When I was in the Navy on submarines, we had a term similar to newbies: "NUB". It stood for "Non-Useful Body". New submariners didn't know how to do anything and they were always asking stupid questions. I feel the same way now as I did when I was a NUB on a sub. Here I guess a "NUPP" would be more appropriate: "Non-Useful Perl Programmer".

Re: Printing file to browser
by how do i know if the string is regular expression (Initiate) on Apr 03, 2001 at 01:25 UTC
    Another method would be to set the "input record separator" ($/).
    undef $/; open (FILE, 'htmlcal.txt'); print "Content-Type: text/html\n\n"; print "What the f***?"; print <FILE>; close FILE;
    This will effectivly make the entire file one record. So using <> in the scalar context will return the entire file.

    I just used this today by chance.

    - FrankG

Re: Printing file to browser
by nysus (Parson) on Apr 03, 2001 at 00:06 UTC
    Tried many of the above suggestions (except for the one that looked like an infinite loop) but to no effect. I'm stumped.
      Nysus,

      I tried your code with a dummy file and it worked fine on my machine. If you are running the code in a cgi-bin directory, you should check your web server log files. It may help to see the contents of your file posted here.

Re: Printing file to browser
by Beatnik (Parson) on Apr 03, 2001 at 14:18 UTC
    Altho this probably won't fix your problem... here's a good tip :

    open (FILE, "<htmlcal.txt") || die $!;

    Ok, so ppl already mentioned die... but it's also pretty nice to define an access mode. When (and you really shouldn't) you read a filename in from user input, you already avoiding pipe abuse.
    This issue is discussed in more depth in RFP's Perl CGI Problems

    Greetz
    Beatnik
    ... Quidquid perl dictum sit, altum viditur.