Sök…


Det manuella sättet

open my $fh, '<', $filename
    or die "Could not open $filename for reading: $!";
my $contents = do { local $/; <$fh> };

Efter att ha öppnat filen (läs man perlio om du vill läsa specifika filkodningar istället för råbyte), är tricket i do blocket: <$fh> , filhandtaget i en diamantoperatör, returnerar en enda post från filen . Variabeln "input record separator" $/ specificerar vad en "record" är - som standard är den inställd på en ny linje-karaktär så "en record" betyder "en enda rad". Eftersom $/ är en global variabel, gör local två saker: det skapar en tillfällig lokal kopia av $/ som kommer att försvinna i slutet av blocket och ger det (icke-) värdet undef (det "värde" som Perl ger till oinitialiserade variabler). När ingångsregistreringsavskiljaren har det (icke-) värdet kommer diamantoperatören att returnera hela filen. (Den anser att hela filen är en enda rad.)

Med do kan du till och med komma runt manuellt att öppna en fil. För upprepad läsning av filer,

sub readfile { do { local(@ARGV,$/) = $_[0]; <> } }
my $content = readfile($filename);

kan användas. Här är en annan global variabel ( @ARGV ) lokaliserad för att simulera samma process som används när man startar ett perl-skript med parametrar. $/ är fortfarande undef , eftersom matrisen framför den "äter" alla inkommande argument. Därefter levererar diamantoperatören <> igen en post definierad av $/ (hela filen) och återgår från do blocket, som i sin tur återvänder från suben.

Subben har ingen uttrycklig felhantering, vilket är dålig praxis! Om ett fel uppstår när du läser filen får du undef som returvärde, i motsats till en tom sträng från en tom fil.

En annan nackdel med den sista koden är det faktum att du inte kan använda PerlIO för olika filkodningar - du får alltid råbyte.

Path :: Tiny

Att använda formspråket från The Manual Way flera gånger i ett skript blir snart tråkigt så du kanske vill prova en modul.

use Path::Tiny;
my $contents = path($filename)->slurp;

Du kan passera ett binmode alternativ om du behöver kontroll över filkodningar, radavslut etc. - se man perlio :

my $contents = path($filename)->slurp( {binmode => ":encoding(UTF-8)"} );

Path::Tiny har också många andra funktioner för att hantera filer så det kan vara ett bra val.

File :: Slurper

Detta är en minimalistisk modul som bara slurper filer till variabler, inget annat.

use File::Slurper 'read_text';
my $contents = read_text($filename);

read_text() tar två valfria parametrar för att ange filkodningen och om radändelser ska översättas mellan unixish LF- eller DOSish CRLF-standarder:

my $contents = read_text($filename, 'UTF-8', 1);

File :: Slurp

Använd inte det. Även om det har funnits länge och fortfarande är den modul som de flesta programmerare kommer att föreslå är den trasig och troligen inte fixad .

Slurping en fil till en matrisvariabel

open(my $fh, '<', "/some/path") or die $!;
my @ary = <$fh>;

Vid utvärdering i listkontext returnerar diamantoperatören en lista som består av alla raderna i filen (i detta fall tilldelar du resultatet till en matrisförrådslista-kontext). Linjeterminatorn hålls kvar och kan tas bort genom chomping:

chomp(@ary); #removes line terminators from all the array elements.

Slurp-fil i enfodral

Inmatningsregistreringsavskiljare kan specificeras med -0 omkopplaren ( noll , inte kapital O ). Det tar ett oktalt eller hexadecimalt värde som värde. Varje värde 0400 eller 0400 kommer att göra att Perl slurper filer, men enligt konventionen är värdet som används för detta ändamål 0777 .

perl -0777 -e 'my $file = <>; print length($file)' input.txt

Att gå vidare med minimalism och att specificera -n switch gör att Perl automatiskt läser varje rad (i vårt fall - hela filen) till variabel $_ .

perl -0777 -ne 'print length($_)' input.txt


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow