What's the best way to open and read a file in Perl?

前端 未结 12 1941
醉话见心
醉话见心 2020-11-27 13:11

Please note - I am not looking for the \"right\" way to open/read a file, or the way I should open/read a file every single time. I am just interested to find out what way m

相关标签:
12条回答
  • 2020-11-27 13:18

    I once used the

    open (FILEIN, "<", $inputfile) or die "...";
    my @FileContents = <FILEIN>;
    close FILEIN;
    

    boilerplate regularly. Nowadays, I use File::Slurp for small files that I want to hold completely in memory, and Tie::File for big files that I want to scalably address and/or files that I want to change in place.

    0 讨论(0)
  • 2020-11-27 13:19

    There are no universal standards, but there are reasons to prefer one or another. My preferred form is this:

    open( my $input_fh, "<", $input_file ) || die "Can't open $input_file: $!";
    

    The reasons are:

    • You report errors immediately. (Replace "die" with "warn" if that's what you want.)
    • Your filehandle is now reference-counted, so once you're not using it it will be automatically closed. If you use the global name INPUT_FILEHANDLE, then you have to close the file manually or it will stay open until the program exits.
    • The read-mode indicator "<" is separated from the $input_file, increasing readability.

    The following is great if the file is small and you know you want all lines:

    my @lines = <$input_fh>;
    

    You can even do this, if you need to process all lines as a single string:

    my $text = join('', <$input_fh>);
    

    For long files you will want to iterate over lines with while, or use read.

    0 讨论(0)
  • 2020-11-27 13:24

    It's true that there are as many best ways to open a file in Perl as there are

    $files_in_the_known_universe * $perl_programmers
    

    ...but it's still interesting to see who usually does it which way. My preferred form of slurping (reading the whole file at once) is:

    use strict;
    use warnings;
    
    use IO::File;
    
    my $file = shift @ARGV or die "what file?";
    
    my $fh = IO::File->new( $file, '<' ) or die "$file: $!";
    my $data = do { local $/; <$fh> };
    $fh->close();
    
    # If you didn't just run out of memory, you have:
    printf "%d characters (possibly bytes)\n", length($data);
    

    And when going line-by-line:

    my $fh = IO::File->new( $file, '<' ) or die "$file: $!";
    while ( my $line = <$fh> ) {
        print "Better than cat: $line";
    }
    $fh->close();
    

    Caveat lector of course: these are just the approaches I've committed to muscle memory for everyday work, and they may be radically unsuited to the problem you're trying to solve.

    0 讨论(0)
  • 2020-11-27 13:27

    There is no best way to open and read a file. It's the wrong question to ask. What's in the file? How much data do you need at any point? Do you need all of the data at once? What do you need to do with the data? You need to figure those out before you think about how you need to open and read the file.

    Is anything that you are doing now causing you problems? If not, don't you have better problems to solve? :)

    Most of your question is merely syntax, and that's all answered in the Perl documentation (especially (perlopentut). You might also like to pick up Learning Perl, which answers most of the problems you have in your question.

    Good luck, :)

    0 讨论(0)
  • 2020-11-27 13:27

    Read the entire file $file into variable $text with a single line

    $text = do {local(@ARGV, $/) = $file ; <>};
    

    or as a function

    $text = load_file($file);
    sub load_file {local(@ARGV, $/) = @_; <>}
    
    0 讨论(0)
  • 2020-11-27 13:37

    If your files are small enough that reading the whole thing into memory is feasible, use File::Slurp. It reads and writes full files with a very simple API, plus it does all the error checking so you don't have to.

    0 讨论(0)
提交回复
热议问题