Skip to content Skip to sidebar Skip to footer

How Do I Read A File's Contents Into A Perl Scalar?

what i am trying to do is get the contents of a file from another server. Since im not in tune with perl, nor know its mods and functions iv'e gone about it this way: my $fileCont

Solution 1:

This is covered in section 5 of the Perl FAQ included with the standard distribution.

How can I read in an entire file all at once?

You can use the Path::Class::File::slurp module to do it in one step.

usePath::Class;
$all_of_it = file($filename)->slurp; # entire file in scalar
@all_lines = file($filename)->slurp; # one line per element

The customary Perl approach for processing all the lines in a file is to do so one line at a time:

open (INPUT, $file) || die"can't open $file: $!";
while (<INPUT>) {
    chomp;
    # do something with $_
}
close(INPUT)        || die"can't close $file: $!";

This is tremendously more efficient than reading the entire file into memory as an array of lines and then processing it one element at a time, which is often—if not almost always—the wrong approach. Whenever you see someone do this:

@lines = <INPUT>;

you should think long and hard about why you need everything loaded at once. It's just not a scalable solution. You might also find it more fun to use the standard Tie::File module, or the DB_File module's $DB_RECNO bindings, which allow you to tie an array to a file so that accessing an element the array actually accesses the corresponding line in the file.

You can read the entire filehandle contents into a scalar.

{
local(*INPUT, $/);
open (INPUT, $file) || die"can't open $file: $!";
$var = <INPUT>;
}

That temporarily undefs your record separator, and will automatically close the file at block exit. If the file is already open, just use this:

$var = do { local $/; <INPUT> };

For ordinary files you can also use the read function.

read( INPUT, $var, -s INPUT );

The third argument tests the byte size of the data on the INPUT filehandle and reads that many bytes into the buffer $var.

Solution 2:

Use Path::Class::File::slurp if you want to read all file contents in one go.

However, more importantly, use an HTML parser to parse HTML.

Solution 3:

open FILE, "c:/perlscripts" . md5_hex($md5Con) . "-code.php"ordie $!;
while (<FILE>) {
    # each line is in $_
}
close(FILE);

will open the file and allow you to process it line-by-line (if that's what you want - otherwise investigate binmode). I think the problem is in your prepending the filename to open with >>. See this tutorial for more info.

I note you're also using regular expressions to parse HTML. Generally I would recommend using a parser to do this (e.g. see HTML::Parser). Regular expressions aren't suited to HTML due to HTML's lack of regularity, and won't work reliably in general cases.

Solution 4:

Also, if you are in need of editing the contents of the files take a look at the CPAN module Tie::File This module relieves you from the need to creation of a temp file for editing the content and writing it back to the same file.

EDIT: What you are looking at is a way to slurp the file. May be you have to undefine the record separator variable $/

The below code works fine for me:

use strict;
my $file = "test.txt";
{
    local( $/ ); # undefine the record seperatoropen FILE, "<", $file ordie"Cannot open:$!\n";
    my $lines =<FILE>;
    print $lines;
}

Also see the section "Traditional Slurping" in this article.

Solution 5:

BUT, for some reason the two regular expresions are returning false. Any idea why?

. in a regular expression by default matches any character except newline. Presumably you have newlines before the </head> tag and after the <body> tag. To make . match any character including newlines, use the //s flag.

I'm not sure what your print $0 . $1 ... code is about; you aren't capturing anything in your matches to be stored in $1, and $0 isn't a variable used for regular expression captures, it's something very different.

Post a Comment for "How Do I Read A File's Contents Into A Perl Scalar?"