2 votes

Comment lire des données partielles dans un grand fichier texte en C++ ?

J'ai un gros fichier texte de plus de 200.000 lignes, et j'ai besoin de lire seulement quelques lignes. Par exemple : ligne 10.000 à 20.000.

Important : je ne veux pas ouvrir et rechercher le fichier complet pour extraire ces lignes en raison de problèmes de performance.

Est-ce possible ?

6voto

rmeador Points 15107

Si les lignes sont de longueur fixe, il serait possible de rechercher une position d'octet spécifique et de charger uniquement les lignes souhaitées. Si les lignes sont de longueur variable, le seul moyen de trouver les lignes que vous recherchez est d'analyser le fichier et de compter le nombre de marqueurs de fin de ligne. Si le fichier change peu souvent, vous pourriez obtenir des performances suffisantes en effectuant cette analyse une seule fois, puis en conservant un index des positions en octets de chaque ligne pour accélérer les accès ultérieurs (peut-être en écrivant cet index sur le disque pour ne pas avoir à le faire à chaque fois que votre programme est exécuté).

1voto

Karl Voigtland Points 5111

Vous devrez parcourir le fichier pour compter les nouvelles lignes, à moins que vous ne sachiez que toutes les lignes ont la même longueur (dans ce cas, vous pouvez rechercher le décalage = numéro de ligne * taille_de_ligne_en_octets, où le numéro de ligne compte à partir de zéro et la taille_de_ligne_en_octets inclut tous les caractères de la ligne).

Si les lignes sont de longueur variable/inconnue, il est possible, lors de la première lecture, d'indexer le début de chaque ligne de manière à ce que les lectures suivantes puissent rechercher le début d'une ligne donnée.

0voto

Brian Ensink Points 7579

Si ces lignes ont toutes la même longueur, vous pouvez calculer un décalage pour une ligne donnée et ne lire que ces octets.

Si les lignes sont de longueur variable, il faut vraiment lire tout le fichier pour compter le nombre de lignes. Les caractères de fin de ligne ne sont que des octets arbitraires dans le fichier.

0voto

Si les lignes sont de longueur fixe, il suffit de calculer le décalage, ce qui ne pose aucun problème.

Si ce n'est pas le cas (c'est-à-dire un fichier CSV normal), vous devrez parcourir le fichier, soit pour créer un index, soit pour lire les lignes dont vous avez besoin. Pour rendre la lecture du fichier un peu plus rapide, une bonne idée serait d'utiliser des fichiers mappés en mémoire (voir l'implémentation qui fait partie de Boost iostreams : http://www.boost.org/doc/libs/1_39_0/libs/iostreams/doc/classes/mapped_file.html ).

0voto

Andrew Y Points 3223

Comme d'autres l'ont fait remarquer, si vous n'avez pas de lignes de largeur fixe, il est impossible de le faire sans construire l'index. Cependant, si vous contrôlez le format du fichier, vous pouvez obtenir une performance de ~O(log(taille)) au lieu de O(taille) pour trouver la ligne de départ, si vous parvenez à stocker le numéro de la ligne elle-même sur chaque ligne, c'est-à-dire pour que le contenu du fichier ressemble à quelque chose comme ceci :

1: val1, val2, val3
2: val4
3: val5, val6
4: val7, val8, val9, val10

Avec ce format de fichier, vous pouvez rapidement trouver la ligne nécessaire par recherche binaire : commencez par chercher au milieu du fichier. Lisez jusqu'à la nouvelle ligne suivante. Ensuite, lisez la ligne et analysez le numéro. Si le nombre est plus grand que la cible, vous devez répéter l'algorithme sur la première moitié du fichier, s'il est plus petit que le nombre de lignes cible, vous devez le répéter sur la deuxième moitié du fichier.

Vous devrez faire attention aux cas particuliers (par exemple : le "début" de la plage et la "fin" de la plage sont sur la même ligne, etc.), mais cette approche a très bien fonctionné dans le passé pour analyser les fichiers journaux contenant la date (et j'avais besoin de trouver les lignes situées entre certains horodatages).

Bien sûr, cela ne bat pas les performances de l'index explicitement construit ou des enregistrements de taille fixe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X