Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Comment lire la totalité du contenu d'un petit fichier texte ?

5 réponses
Avatar
Yves Martin
Comment remplacer
$contenu = `cat $FICHIER`;
le plus élégament possible (portable, court et avec la gestion des erreurs
correctes) sans forker un bash et un cat ?

--
Yves Martin

5 réponses

Avatar
Paul Gaborit
À (at) Thu, 15 Dec 2005 15:01:43 +0100,
Yves Martin écrivait (wrote):
Comment remplacer
$contenu = `cat $FICHIER`;
le plus élégament possible (portable, court et avec la gestion des erreurs
correctes) sans forker un bash et un cat ?


Qu'est-ce que c'est "des erreurs correctes" ? Ou alors c'était la
gestion qui était "correcte"... ;-)

sub cat {
my $fichier = shift;
open my $fh, "<", $fichier
or die "Pb de lecture de '$fichier' : $!n";
local $/ = undef;
my $contenu = <$fh>;
close $fh
or die "Pb de fermeture de '$fichier' : $!n";
return $contenu;
}

# à utiliser comme ça :
my $contenu = cat($FICHIER);

PS: il reste au moins une erreur potentielle non gérée : le
dépassement de capacité mémoire si le fichier est trop gros.

PS2: pour être complétement portable, il faudrait aussi se poser la
question des fichiers binaires sur les plateformes qui distinguent les
fichiers binaires des fichiers textes...

PS3: le 'court' et le 'portable' ne font pas toujours bon ménage ;-)

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Yann Coscoy
Yves Martin wrote:


Comment remplacer
$contenu = `cat $FICHIER`;
le plus élégament possible (portable, court et avec la gestion des
erreurs correctes) sans forker un bash et un cat ?



Dans un contexte de liste, l'opérateur diamant prend tout le fichier. Cela
donne :

open (IN, "<", $FICHIER);
my @l = <IN>;
close IN;

Yann Coscoy

Avatar
Michel Rodriguez
Yves Martin wrote:
Comment remplacer
$contenu = `cat $FICHIER`;
le plus élégament possible (portable, court et avec la gestion des erreurs
correctes) sans forker un bash et un cat ?



use File::Slurp;
my $text = read_file( 'filename' ) ;

la gestion des erreurs est assuree par une option:

err_mode
You can use this option to control how read_file behaves when an
error occurs. This option defaults to 'croak'. You can set it to
'carp' or to 'quiet to have no error handling. This code wants to
carp and then read another file if it fails.

# Ndm: il y a visiblement une erreur dans la doc, il manque l'option
# scalar_ref => 1, je l'ai rajoutee
my $text_ref= read_file( $file, err_mode => 'carp', scalar_ref => 1) ;
unless ( $text_ref ) {
# read a different file but croak if not found
$text_ref = read_file( $another_file ) ;
}
# process ${$text_ref}

Avatar
Paul Gaborit
À (at) Fri, 16 Dec 2005 10:36:11 +0100,
Michel Rodriguez écrivait (wrote):
use File::Slurp;


Tiens, c'est vrai. Je l'avais oublié celui-là. La longueur de la
documentation (même incomplète) donne une idée de tout ce qu'on peut
rencontrer comme situation autour d'un simple 'slurp'.

Un passage sympathique :

You can optionally request that "slurp()" is exported to your
code. This is an alias for read_file and is meant to be forward
compatible with Perl 6 (which will have slurp() built-in).

J'adore le 'forward compatible'. C'est du Perl comme je l'aime ;-)

Merci Michel.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Michel Rodriguez
Paul Gaborit wrote:
À (at) Fri, 16 Dec 2005 10:36:11 +0100,
Michel Rodriguez écrivait (wrote):

use File::Slurp;



Tiens, c'est vrai. Je l'avais oublié celui-là. La longueur de la
documentation (même incomplète) donne une idée de tout ce qu'on peut
rencontrer comme situation autour d'un simple 'slurp'.

Un passage sympathique :

You can optionally request that "slurp()" is exported to your
code. This is an alias for read_file and is meant to be forward
compatible with Perl 6 (which will have slurp() built-in).

J'adore le 'forward compatible'. C'est du Perl comme je l'aime ;-)


Bon, c'est l'heure d'avouer ses pcéhés...

En fait, dans beaucoup de cas, je recode les fonctions slurp et spit
('inverse, File::Slurp appelle ca spew). En general c'est 3 lignes
chaque, mais souvent l'interface est un peu differente: dans slurp des
fois je veux recuperer une reference a une chaine, ou pouvoir "slurper"
une URL, ou un pipe (exclu de File::Slurp) ou des trucs comme ca. Dans
spit je veux pouvoir passer une reference a une chaine, ou plusieurs
chaines, et d'autres trucs que j'oublie. En plus les conditions
d'erreurs dependent du code, j'aime bien ecrire my $html= slurp( $CACHE)
|| slurp( $URL); par exemple. Donc plutot que de me rappeler de toutes
les options du module, je me re-invente ma petite roue pas tout a fait
ronde. Bien sur ca ne marche que pour des projets simples ou toutes les
operations de slurp/spit ont les memes caracteristiques, mais en
pratique c'est souvent le cas.

Ah, je me sens soulagé.

--
michel