lecture fichier par bundle de lignes - Perl - Programmation
Marsh Posté le 14-03-2005 à 15:55:14
Il y a un pb, la taille de mes ligne n'est pas fixe.
Alors que la taille que tu m'indique est en byte.
Marsh Posté le 14-03-2005 à 19:47:13
Si tu utilises <> dans un contexte scalaire, ca lit une ligne. Et si tu fais une petite boucle genre "for my $i (1..10) push(@FileTab, scalar <> );", tu lira n lignes.
Marsh Posté le 14-03-2005 à 22:12:10
open(FILE_IN,"<toto.txt" )|| die "bla bla bla";
while <FILE_IN> {
action quelquonque
encore
}
Dans la boucle, $_ représente la ligne courante, et il lit toute les lignes une par une ..
Marsh Posté le 15-03-2005 à 08:50:37
Oui, j'avais pensé a cette solution. Mais je voulais pouvoir limitter les access disques. Et recuper un paquet de donnees suffisant sans avoir a lire le disque pour chaque ligne et plus tot travailler en memoire.
Marsh Posté le 15-03-2005 à 12:14:31
pour travailler en mémoire c'est tout mettre dans un tableau
d'ailleurs il est recommandé de le faire, j'ai lu ca dans les bonnes pratiques perl chais plus où
Marsh Posté le 15-03-2005 à 12:21:21
mandracke76 a écrit : .. Mais je voulais pouvoir limitter les access disques. Et recuper un paquet de donnees suffisant sans avoir a lire le disque pour chaque ligne ... |
Et à ton avis, ça "my @FileTab = <FILE_IN>;" ça fait quoi ?
La solution de matafan convient ... et est même de loin la plus cohérente ! Enfin en rajoutant le contrôle de fin de fichier etc etc ... mais le principe est là ...
TU dois compter toi-même le nombre de ligne que tu lis, push dans un tableau et traite ...
Marsh Posté le 15-03-2005 à 12:23:04
Oui mais quand tu as un fichiers plus d'un milion de ligne, qui correspond a un extract de base. Je te raconte pas la prise de place en memoire.
Marsh Posté le 15-03-2005 à 12:26:35
mandracke76 a écrit : Oui mais quand tu as un fichiers plus d'un milion de ligne, qui correspond a un extract de base. Je te raconte pas la prise de place en memoire. |
Mais non ! ..
Quand tu as traité tes N lignes lues et mises en mémoire dans un tableau ben tu vires le contenu du tableau et tu le réutilises pour les loads suivants !!! ...
Maintenant c'est clair que si le traitement de la ligne 282.456 a besoin de la ligne 6 ... c'est clair que c'est foireux !
( faut dire que tu n'as pas précisé le type de traitement que tu veux faire )
Marsh Posté le 15-03-2005 à 13:21:58
Non dans mon programme je n'ai pas d'interaction entre la ligne i et la ligne i+1000 ou -1000.
Mais ma principale preoccupation est d'eviter de creer un tableau en memoire de plus d'un milion de ligne. Et pouvoir lire le contenue du fichier sans faire un acces disque a chaque fois que je veux lire le fichier.
Marsh Posté le 15-03-2005 à 13:47:04
si tu fais une lecture ligne par ligne (avec un while et un <> en contexte scalair) ca ne fera pas pour autant plus d'acces disque: il n'y aura pas un acces disque par ligne lue, car Perl utilise une couche d'abstraction pour les IO avec un systeme de cache. En gros à ta premier lecture il va lire (par exemple) 8ko, et ne refera un nouvel acces disque que kand ce tampon sera epuisé (pour charger à nouveau 8ko). Donc pas de probleme d'efficacité.
Marsh Posté le 15-03-2005 à 13:51:32
mandracke76 a écrit : |
DONC il faut lire ton fichier par bloc, mettre en mémoire, traiter, virer le tableau en mémoire et continuer la lecture jusqu'à plus de lignes ...
mandracke76 a écrit : |
DONC il faut lire tout le fichier d'un coup et le mettre dans un tableau en mémoire ..
Je n'ai même pas l'impression que tu te rends compte du caractère totalement antagoniste de ce que tu dis ......
Marsh Posté le 14-03-2005 à 13:37:41
bonjour,
Je sais qu'il est facile de charger en memoire tout le contenue d'un fichier dans un tableau en perl:
#Ouverture fichier
open(FILE_IN, "< toto.txt" ) || die "ERROR - $! : toto.txt\n";
# Chargement dans un tableau
my @FileTab = <FILE_IN>;
# Fermeture du fichier
close FILE_IN;
#Lecture ligne à ligne
foreach (@FileTab){
s/[\r|\n]*//g;
...
}
Mais dans mon cas le fichier risque de contenir enormement de lignes, alors je voudrais avoir la possibilité de charger mon fichier par block de 'n' lignes à la fois.
Est ce possible, de preference sans proceder à un appel system de type split?
Merci d'avance.