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.
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.
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; }
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;
}
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; }
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ï
Laurent Wacrenier wrote:
Jedaï <chaddai@wanadoo.fr> é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é !
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é !