OVH Cloud OVH Cloud

Inserer une ligne dans un fichier

3 réponses
Avatar
dalshim
Bonjour tout le monde. Juste une question rapide :

Je voudrais insérer quelques lignes dans un fichier texte. Je pourrais,
allez vous me dire, ouvrir deux flux, l'un qui lit, l'autre qui écrit.
Mais le problème, c'est que mon fichier est assez gros (près de 50 MO),
et que je rechigne un peu à ouvvrir deux flux. Je me demandais donc s'il
n'y avait pas un fonction simple, prédéfinie, qui pourrait me permettre
de faire ça.

Merci d'avance

3 réponses

Avatar
dalshim
Denis -esp2008- wrote:
Bonjour,

Je voudrais insérer quelques lignes dans un fichier texte.


Tout dépend s'il s'agit d'une insertion en début, en fin ou ailleurs
dans le fichier, il faudrait plus de précisions :)

---
Denis



En fin, pas de problème...

C'est plutôt une insertion dans le corps du fichier. Cela peut donc être
au début ou ailleurs dans le fichier.


Avatar
Jedaï
dalshim wrote:

Denis -esp2008- wrote:

Bonjour,

Je voudrais insérer quelques lignes dans un fichier texte.



Tout dépend s'il s'agit d'une insertion en début, en fin ou ailleurs
dans le fichier, il faudrait plus de précisions :)

---
Denis



En fin, pas de problème...

C'est plutôt une insertion dans le corps du fichier. Cela peut donc être
au début ou ailleurs dans le fichier.



C'est juste un truc que j'avais griffoné pour expliquer à quelqu'un
comment utiliser le mode lecture-écriture de fichier, mais la fonction
peut insérer n'importe où dans le fichier (ici, à la suite d'une ligne
contenant __DATA__), à toi d'améliorer la fonction si tu t'en sens le
courage (d'autant plus que ce genre de truc doit bien faire l'objet d'un
module), bien sûr, il faut que tu considère le nombre d'insertions à
effectuer, à part en améliorant carrément l'algorithme (un minimum
serait de fonctionner par bloc de taille arbitraire après ajustement),
si tu as plusieurs insertions, il vaut sans doute mieux utiliser deux flux :

#!/usr/bin/perl

#notez qu'on suppose que le fichier est en ASCII,
#ou en tout cas qu'un caractère vaut un octet

#attention '+>' ouvre le fichier en lecture/écriture et efface son
contenu !!!
#ici on ouvre en lecture/écriture avec '+<' et on rajoute ':raw' pour
l'ouvrir en
#mode binaire (utile sous Windows, surtout en r/w !)
open RWFILE,'+<:raw', 'c:/Mes documents/testrw.txt' or
die "Impossible d'ouvrir bidule en lecture/écriture : $! n";
my $length = 0;
$length += length $line while( defined($line = <RWFILE>) and ($line !~
m/__DATA__r?$/m) );
$length += length $line;

#supprimé pour test de "inserer"
#truncate RWFILE, $length;

#par mesure de sécurité :
seek RWFILE, $length, 0;
$modif = "Ma ligne à insérern";
inserer( RWFILE, $modif );
print "C'est OK n";

sub inserer {
use bytes;
my( $fh, $modif ) = @_;
my $init = tell $fh;
my $ln = length( $modif );
my ($save, $pos);
while( not eof( $fh )) {
$pos = tell $fh;
read( $fh, $save, $ln );
seek $fh, $pos, 0;
print $fh $modif;
$modif = $save;
}
print $fh $modif;
seek $fh, $init, 0;
}



Avatar
Jedaï
Laurent Wacrenier wrote:

Jedaï écrit:

C'est juste un truc que j'avais griffoné pour expliquer à quelqu'un
comment utiliser le mode lecture-écriture de fichier, mais la fonction
peut insérer n'importe où dans le fichier (ici, à la suite d'une ligne
contenant __DATA__), à toi d'améliorer la fonction si tu t'en sens le
courage (d'autant plus que ce genre de truc doit bien faire l'objet d'un
module), bien sûr, il faut que tu considère le nombre d'insertions à
effectuer, à part en améliorant carrément l'algorithme (un minimum
serait de fonctionner par bloc de taille arbitraire après ajustement),
si tu as plusieurs insertions, il vaut sans doute mieux utiliser deux flux :



Surtout si on a pas assez de mémoire pour conserver la fin du fichier
ou si les données sont précicieuses.


Le problème de mémoire n'en est pas un avec ma fonction puisque je
décale par bloc de la taille de l'insertion (évidemment si l'insertion
est trop grosse....), donc la fin de fichier n'est jamais entièrement en
mémoire. Par contre c'est certain que si les données sont précieuses...
Mais dans ce cas, on espère bien qu'un backup a été effectué !

--
Jedaï