IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Lecture de fichiers .txt volumineux


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2013
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2013
    Messages : 80
    Par défaut Lecture de fichiers .txt volumineux
    Bonjour,

    Cette discussion vient en parallèle à un autre post : http://www.developpez.net/forums/d14...hiers-paradox/

    Je dois lire des fichiers .txt qui peuvent dans certains cas être très volumineux. Je me suis dit que peut être il y'aurait moyen d'alléger la méthode de lecture que j'utilise.

    Voici ce que je fais :
    On définit dans mon programme une date de début et une date de fin.
    Je dois lire dans un à 3 fichiers (boucles imbriquées) qui sont formés comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    01/01/2014;1;1;0;3.5;2
    01/01/2014;1;2;0;7;2
    02/01/2014;3;1;0;5;4
    //Ainsi de suite ...
    Ce que je fais dans mon code : je parcours chaque ligne du fichier en séparant par le ; chaque élement et en comparant l'élement 0 (la date) si elle est entre les dates de début et fin, si oui je fais récupère d'autres éléments de la ligne en cours pour calculer, vérifier autre chose.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    string monFichier = _file.GetCheminFichierExport("MON_GROS_FICHIER.TXT"); // Je récupère le chemin du fichier passé en paramètre
    string[] sep = {";"}; // Je définis le ; comme séparateur
    foreach (
    var elem in
    File.ReadLines(monFichier, System.Text.Encoding.Default)
                            .Select(elem => elem.Split(sep, StringSplitOptions.None)) // Je split les éléments de chaque ligne par le séparateur que j'ai défini
                                {
                                        //Ici mon traitement
                                }
    Voilà à peu près ce que je fais, en sachant que je peux avoir un ou deux foreach qui peuvent s'imbriquer dans le principal foreach; en sachant que certains fichiers ont des dates qui remontent à 2012 (environ 400Mo le .txt), je comprends que ça peut prendre du temps.

    Ma méthode de traitement est elle bonne ou y'a t il un moyen d'optimiser cette fonction pour faire plus rapide ?

    Merci.

  2. #2
    Membre éclairé
    Inscrit en
    Novembre 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 40
    Par défaut
    Avec ta methode il risque de tout monter en mémoire pour gerer toutes les lignes.

  3. #3
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Si l'optimisation est bien l'objectif recherché et si les dates sont triées en ordre croissant, on peut utiliser un StreamReader sur le fichier et faire appel à sa fonction BaseStream.Seek().

    Dans un premier temps, on peut "découper" le fichier en blocks :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (int SeekPos=0;seekPos<FileSize-1000;SeekPos+=BlockSize)
    {
      // on fait un Seek(SeekPos) pour se positionner dans le fichier par pas de quelques mega,
      // on recherche la premiere occurence d'une date et on note dans une liste cette date et sa position dans le fichier
    }
    Quand on cherche une date supérieure à D1 et inférieure à D2, on se repositionne au début et on fait un Seek() avec la position de la liste correspondant à la dernière date inférieure à D1 (et on arrète le traitement dès qu'on trouve une date > D2).

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2013
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2013
    Messages : 80
    Par défaut
    La taille du fichier peut varier Graffito.
    Et dans tous les cas il faudra quand même arriver à la première occurence qui correspond à la date D1.
    Enfin je me renseigne quand même sur ta proposition je ne connaissais pas

    Drezounet, j'ai essayé mais ça reste pareil, merci quand même !

  5. #5
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    il faudra quand même arriver à la première occurence qui correspond à la date D1.
    En découpant vitruellement le grand fichier en intervalles (de 1 Mo par exemple), on a juste besoin d'analyser le tout début de chaque intervalle (quelques dizaines d'octets) pour identifier un block avec sa première date.

    On peut ensuite démarrer sur le dernier block dont la date est inférieure à D1, sans lire les blocks précédents.


    J'avais divisé la methode en 2 étapes pour plus de compréhension, mais on peut opérer ainsi :
    1) Déplacer la position de lecture sur le debut de l'intervalle n (SeekPos = n*Taille_de_l'intervalle),
    2) identifier la position Pn de la première date de l'intervalle n,
    3) si Dn inférieure à D1, boucler sur 1)
    4) si Dn supérieure ou égale à D1, on commence le traitement séquentiel à la position Pn-1.

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2013
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2013
    Messages : 80
    Par défaut
    Oops toutes mes excuses Graffito ! J'avais complètement oublié de poster une réponse.

    Du coup oui, ta solution a l'air d'être intéressante, mais je n'ai pas trouvé d'exemple concret en C#. Tu as un exemple de code ?

Discussions similaires

  1. [Debutant] Lecture de fichier txt
    Par vbbarent dans le forum Débuter
    Réponses: 11
    Dernier message: 06/05/2008, 11h13
  2. Problème de lecture de fichier .txt
    Par Lenaick dans le forum WinDev
    Réponses: 4
    Dernier message: 16/04/2008, 11h49
  3. [PC] [Visual Object Cobol] Lecture de fichier .txt
    Par vince3132 dans le forum Cobol
    Réponses: 7
    Dernier message: 14/03/2008, 13h43
  4. [Excel - VBA] lecture de fichier txt
    Par simstef dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 15/06/2007, 16h00
  5. PL/SQL lecture/ecriture fichier txt
    Par stos dans le forum PL/SQL
    Réponses: 2
    Dernier message: 19/05/2006, 12h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo