Récupérer la position de début et fin de string dans un fichier c#
Karibot
Messages postés89Date d'inscriptionmardi 19 janvier 2010StatutMembreDernière intervention21 juin 2016
-
28 oct. 2011 à 19:09
cs_jopop
Messages postés1540Date d'inscriptionlundi 26 mai 2003StatutMembreDernière intervention 1 août 2013
-
18 nov. 2011 à 08:54
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;
}
}
Whismeril
Messages postés18640Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 2 octobre 2023629 28 oct. 2011 à 21:11
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>.
Karibot
Messages postés89Date d'inscriptionmardi 19 janvier 2010StatutMembreDernière intervention21 juin 20162 29 oct. 2011 à 11:02
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
Whismeril
Messages postés18640Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 2 octobre 2023629 29 oct. 2011 à 11:55
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....
}
Karibot
Messages postés89Date d'inscriptionmardi 19 janvier 2010StatutMembreDernière intervention21 juin 20162 30 oct. 2011 à 09:52
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?
Vous n’avez pas trouvé la réponse que vous recherchez ?
cgandco
Messages postés219Date d'inscriptionmercredi 26 octobre 2011StatutMembreDernière intervention22 juin 20179 17 nov. 2011 à 17:46
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.