Récupérer la position de début et fin de string dans un fichier c#

Signaler
Messages postés
89
Date d'inscription
mardi 19 janvier 2010
Statut
Membre
Dernière intervention
21 juin 2016
-
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
-
Bonjour,
je cherche à indexer un gros fichier de données qui contient des blocs identiques de 4 lignes chacun. voici la structure de mon fichier:
item->velue
date->value
desc->value

ce que je souhaire faire c'est créer un index (dictionnary<string, string>) du couple item -> desc, sauf que "desc" est une une grande chaine de caractètres, très longues... donc prend de la memoire quand je la charge via des regex (outofmemory). oui parce qu'au début, je récupérais les elements de mon index grace à des regex et je stockais dans mon dico les valeur de item->desc...

la ce que j'ai essayé de faire c'est d'au lieu de chercher à stocker toute la chaine, je vais juste stocker les positions de début et de fin du "desc". donc j'aimerai avoir au final dans mon dico un couple item->pos_debut;pos_fin, sauf que je n'y arrive pas, cela me sort un truc bizarre!
je vous laisse mon code, et espère que quelqu'un puisse m'éclairer sur le sujet.
            Dictionary<string, string> Index = new Dictionary<string, string>();
            oRd = new StreamReader(file);
            string l;
            string item = string.Empty;
            long pos_debut = 0;
            long pos_fin = 0;
            while ((l = oRd.ReadLine()) != null)
            {
                if (l.StartsWith("item"))
                    item = l.Split('\t')[1];
                else if (l.StartsWith("date"))
                {
                    //je suppose que le pointeur et au bout de la ligne donc commence le début de la ligne suivante
                    pos_debut = oRd.BaseStream.Position;
                }
                else if (l.StartsWith("desc"))
                    pos_fin = oRd.BaseStream.Position;
                else
                    continue;

                if (!string.IsNullOrEmpty(item) && pos_debut > 0 && pos_fin > 0)
                {
                    if (!Index.ContainsKey(item))
                        Index.Add(item, pos_debut+";"+pos_fin);
                    else
                        continue;

                    item = string.Empty;
                    pos_debut = 0;
                    pos_fin = 0;
                }
            }


merci pour vos réponses!

7 réponses

Messages postés
15407
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
20 janvier 2021
502
Bonsoir,

peux tu donner quelques lignes d'exemple de ton fichier.
Quand je teste ton code avec des lignes que j'ai imaginé, BaseStream.Position me retourne toujours la même valeur.

D'autre part, le dictionnaire ne me parait pas la meilleure solution,
puisque tu cherches à enregistrer 3 paramètres.

A ta place je créerai une classe avec Item, Debut et Fin et je stockerai les occurrences dans une List<T>.



Whismeril
Messages postés
89
Date d'inscription
mardi 19 janvier 2010
Statut
Membre
Dernière intervention
21 juin 2016
2
ben le fichier est comme je l'ai décrit plus haut voici un exemple:
item->dvd
date->12092011
desc->GFT65REIJFU876RYT6YEBFUD9875URJE0PMSLKF,FJU54GGDTEHDJJDKFSMXW01H13N8...

les "->" = tabulation

merci pour le conseil concernant la classe, je vais certainement le suivre, mais cela ne régle pas mon problème de positions

merci pour ta réponse!
Messages postés
15407
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
20 janvier 2021
502
J'ai fait 3 lignes de ce format (enfin presque pour la date j'avais mis 12/09/2011), et la position retournée à chaque BaseStream.Position est la même, et est égale au nombre de caractères de mon fichier test.
Je ne trouve pas de fonction donnant la position de la ligne dans le flux, alors je te propose un truc dans ce style:

            while ((l = oRd.ReadLine()) != null)
            {
                l2 = oRd.ReadLine();//ligne date
                l3 = oRd.ReadLine();// ligne desc
                pos_debut = l.Length+ l2.Length;
                pos_fin = pos_debut + l3.Length;

                MaClasse MaClasse = new MaClasse(l.Split('\t')[1], pos_debut, pos_fin);
                //etc....

            }


Whismeril
Messages postés
89
Date d'inscription
mardi 19 janvier 2010
Statut
Membre
Dernière intervention
21 juin 2016
2
hello,
je suis en train de tester ta méthode avec pas mal de modifications :)

je récupére bien mon tableau item->positions, et la j'essaye de lire dans le fichier suivant les positions. donc je fais:
int count = pos_fin - pos_debut;
char[] buffer = new char[count];
oRd.ReadBlock(buffer, pos_debut, count);


mais il bute sur le readblock avec cette erreur:
"l'offset et la longueur étaient hors limites pour ce tableau ou bien le nombre superieur au nombre d'éléments de l'index à la fin de la collection source"

j'ai essayer d'augmenter la taille du buffer pour qu'il soit supérieur au count mais j'ai toujours la meme erreur...

une idée?
Messages postés
15407
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
20 janvier 2021
502
Bonjour,

je contaste la même chose.
Ca ne marche qu'avec

oRd.ReadBlock(buffer, 0, count);


Je ne comprends pas pourquoi.

Je ne vois qu'une boucle pour lire n blocks jusqu'à arriver à la bonne position.
Pas glop.
Je n'ai pas la solution désolé.

Whismeril
Messages postés
219
Date d'inscription
mercredi 26 octobre 2011
Statut
Membre
Dernière intervention
22 juin 2017
9
Bonjour à tous,

Mille excuses pour le retard.

Ceci ne peut-il pas provenir du fait que "readline" n'enregistre (a mon avis) pas les [CR][LF] etc... alors que pour "readblock" ils sont stockés car c'est un tableau de char.

Un décalage doit donc se produire à cet endroit.

il faut peut être calculer pos_debut et pos_fin en ajoutant le nombre de caractères non stocké par "readline" avant de les mettre dans le dictionnaire ou la list.

C'est simplement une idée sans avoir testé.

Bonne soirée
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
Salut,

quelle taille a ton fichier de données ?
j'ai du mal à imaginer une OutOfMermoryException hors fuite mémoire (ou alors avec un fichier de presque 2Go)