Souci avec ReadLine (StreamReader)

Résolu
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 - 24 août 2005 à 11:15
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 - 25 août 2005 à 15:35
Salut,



je voudrais extraire une partie d'un fichier txt qui se trouve au
milieu de ce dernier. Seul moyen d'identifier la partie en question, le
début des lignes est connu.



Par exemple, le fichier ressemble à ceci :



debut1...

debut2...

debut3...

milieu1...

milieu2...

milieu3...



milieu4...



fin1...

fin2...

fin3...


Je me sers pour l'instant de l'algo suivant pour extraire la partie qui
commence par milieu, mais ce n'est pas satisfaisant, il me manque la
première ligne qui commence par "milieu" :



try

{


using (StreamReader sr = new
StreamReader(File_Name))

{

string line;


while
((line=sr.ReadLine()).StartsWith("ENTET"))

{



string_DEFETAT = "";

}


while
(!(line=sr.ReadLine()).StartsWith("MES"))

{



string_DEFETAT +=line + "\n";

}

sr.Close();

}

}



Ce code me donne :


milieu2...

milieu3...



milieu4...




J'ai essayé un autre code qui me donne :


milieu1...

milieu3...






Mais je n'arrive pas à avoir tout ce qui commence par
milieu. Si vous voulez bien m'aider, je sais que c pas dur, mais bon,
quand on bloque.. on bloque

20 réponses

Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
24 août 2005 à 18:35
Salut, c'est ça que tu essayes de faire ?

string s = string.Empty;
string line = string.Empty;
sr = new StreamReader( "Test.txt" );


while( ( line = sr.ReadLine( ) ) != null )
{
if ( line.StartsWith( "milieu" ) )
s += line + "\n";
}


//MessageBox.Show( s );


sr.Close( );
3
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
25 août 2005 à 10:35
décidément... "^milieu.*$"


<HR>
Sébastien FERRAND

Blog :
3
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
25 août 2005 à 10:46
essaye celle-ci : "^milieu.*$"

Sébastien FERRAND
3
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
24 août 2005 à 11:16
try
{


using (StreamReader sr = new
StreamReader(File_Name))
{
string line;


while
((line=sr.ReadLine()).StartsWith("debut"))
{



string_DEFETAT = "";
}


while
(!(line=sr.ReadLine()).StartsWith("fin"))
{



string_DEFETAT +=line + "\n";
}
sr.Close();
}
}
C'est plutôt ca l'algo dans le cas de l'exemple :-)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
24 août 2005 à 11:28
si tu connais le début de la ligne, pourquoi ne pas utiliser une expression régulière ?


<HR>
Sébastien FERRAND

Blog : http://blogs.developpeur.org/sebmafate
0
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
24 août 2005 à 11:31
Hmmm, c koi une expression régulière ?



Sinon, j'ai trouvé une solution, mais c de la bidouille je pense ...

try
{


using (StreamReader sr = new
StreamReader(File_Name))
{
string line;


while
((line=sr.ReadLine()).StartsWith("debut"))
{



string_DEFETAT = "";
}

string_DEFETAT = line ;



while
(!(line =sr.ReadLine()).StartsWith("fin"))
{



string_DEFETAT +=line + "\n";
}
sr.Close();
}
}

Ca me rajoute bien la première ligne que je n'arrivais pas à avoir...



>Seb : je veux bien que tu montres une meilleure méthode si tu as 5 min
0
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
24 août 2005 à 11:36
Apparemment, c'est une sorte de masque ? Si tu veux bien me montrer ce que ca donnerait dans mon cas, je suis preneur...
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
24 août 2005 à 11:54
en fait, tu charges ton fichier dans une string (ReadToEnd())
ensuite, tu utilises une expression régulière qui te retournera l'ensemble des lignes qui correspondent.
par exemple :

System.Text.RegularExpressions.Regex regex =

new System.Text.RegularExpressions.Regex(
"^debut");

regex.Matches(fichier)

te retourne une collections de Match contenant toutes les lignes qui commence par "debut".

Je te conseille de lire la doc pour en connaitre un peu plus sur les expressions régulières : http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/cpref/html/frlrfsystemtextregularexpressionsregexclasstopic.asp


<HR>
Sébastien FERRAND

Blog : http://blogs.developpeur.org/sebmafate
0
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
25 août 2005 à 10:16
>Seb, j'ai un petit doute, j'ai testé ta solution mais ca ne marche
pas, et je suppose que cela vient, en partie, du fichier, et en autre
partie de la syntaxe.

En effet, c'est moi qui ai crée les fichiers dans lesquels je
recherche, et ces fichiers en question n'ont que \n à la fin de la
ligne et non pas \r\n.

Puisque je veux l'ensemble de toutes les lignes qui commencent par le
texte recherché, est-ce qu'il ne faut pas qu'il y ait plutôt \r\n à la
fin des lignes pour qu'il prenne ça comme des vrais fin de ligne ?

Car quand j'ouvre mon fichier avec textpad, tout est collé, alors qu'avec wordpad, il affiche bien les sauts de lignes.



Sinon, j'ai donc essayé ceci :

System.Text.RegularExpressions.Regex regex =


new
System.Text.RegularExpressions.Regex("^milieu");

try

{


using (StreamReader sr = new
StreamReader(File_Name))

{


fichier =
sr.ReadToEnd();



System.Text.RegularExpressions.MatchCollection a =



regex.Matches(fichier);


foreach
(System.Text.RegularExpressions.Match valeur in a)

{



resultat += valeur;

}

}

}
Cela ne me retourne rien.

Avec ceci comme regex :

System.Text.RegularExpressions.Regex regex =


new
System.Text.RegularExpressions.Regex("^debut");

cela me retourne 1 match qui est "debut" tout court, sans la phrase derrière.



N'y a t-il pas un problème au niveau de la syntaxe ^milieu ?
D'une part, parcequ'il ne va pas le chercher au milieu du texte
apparemment, et d'autre part, parcequ'il ne retourne pas aussi le
contenu de la phrase entière.



>Lutinore : j'ai testé ton code ci dessus, apparemment, ca marche
impeccable, maintenant reste à savoir laquelle des deux méthodes est la
plus rapide (les fichiers vont de qqls ko à disons 500Ko)



Mais pour l'instant, je n'ai pas trouvé la méthode avec regex donc je v m'orienté vers ta méthode Lutinore.
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
25 août 2005 à 10:26
je me suis trompé dans l'expression régulière

"^milieu\w*$" et ajouter l'option RegexOptions.Multiline

Sébastien FERRAND
0
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
25 août 2005 à 10:40
J'ai du rajouter un @ devant "^milieu\w*$" car il me dit séquence
d'échappement non reconnue (mais ca me retourne quand meme 0 match). Tu
n'aurais pas encore oublié un pitit truc ?
0
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
25 août 2005 à 10:41
J'ai aussi essayé de doubler le \, car je me rappelle avoir vu ca un coup, mais ca ne marche pas non plus :-/

càd : "^milieu\\w*$"
0
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
25 août 2005 à 10:45
Bon, j'avais pas vu ton dernier post. Sinon, je serais d'accord avec
toi pour ".*" qui compte autant de car qu'il faut pour aller à $ qui
est la fin de la ligne, mais ca ne marche pas. Est-ce que tu penses pas
que ca vienne de mon fichier qui n'a que des \n et pas des \r\n ?
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
25 août 2005 à 10:48
c'est possible... dans ce cas, sur ta chaine fait un .Replace("\n","\r\n")

Sébastien FERRAND
0
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
25 août 2005 à 11:35
Bon suite à mes quelques tests (pour vous départager, lol
), j'ai obtenu les résultats suivants, qu'il faut interpréter avec
précaution, car les résultats sont variables d'un test à l'autre et
aussi si on répète plein de fois le test (ca c mon programme qui est
mal fait, c'est autre chose ) :



Le test consistait à retourner 95% du fichier : (car 95% commence par le même mot) :

fichier de 90ko :
méthode readline : environ 2300 ms

méthode regex : de 40 à 50 ms environ



fichier de 59ko :

méthode readline : environ 1300 ms


méthode regex : de 10 à 50 ms environ



Voilà pour clore ce sujet, Regex est énormément plus rapide que la lecture par Readline().

Merci de votre aide...
0
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
25 août 2005 à 11:41
Bon je pensais avoir mis la solution avant mon précédent post, mais le
site rame tellement à ma boîte, que le post n'est pas passé apparemment.

Je précisais que les deux méthodes marchaient, et que j'allais faire des tests pour voir la plus rapide :



voilà le code qui marche, il fallait bien préciser l'option "multiline" lors de la création de l'objet regex :



System.Text.RegularExpressions.RegexOptions Option =



System.Text.RegularExpressions.RegexOptions.Multiline;

System.Text.RegularExpressions.Regex regex =


new
System.Text.RegularExpressions.Regex("^DEFETAT.*$",Option);



try

{


using (StreamReader sr = new
StreamReader(File_Name))

{


fichier =
sr.ReadToEnd();



System.Text.RegularExpressions.MatchCollection a =



regex.Matches(fichier);


foreach
(System.Text.RegularExpressions.Match valeur in a)

{



resultat += valeur;

}

}

}
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
25 août 2005 à 12:08
Merci pour ces precisions.

Sébastien FERRAND
0
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 9
25 août 2005 à 13:39
Quand à faire, j'aimerais améliorer mon code. Je suis sur que je peux
encore accélérer cette routine, car j'utilise un string pour stocker
l'ensemble des match trouvés.

resultat += valeur;

Je me rappelle que l'on m'avait déjà conseillé de faire gaffe avec
l'utilisation de string dans ce cas précis (où je stocke au fur et à
mesure une importante quantité).



Vous qui connaissez sans doute mieux que moi les objets que propose la
classe text, ou une autre classe, il n'y aurait pas mieux à faire, avec
je sais pas un streamreader, ou un autre objet dans le style qui serait
mieux approprié à stocker une phrase assez longue (genre 90Ko) ?
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
25 août 2005 à 13:51
Utilise un StringBuilder, dans System.Text.

Sébastien FERRAND
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
25 août 2005 à 15:35
C'est ReadToEnd qui est plus rapide qu'une boucle avec ReadLine. Et les méthodes de la classe String c'est pas terrible au niveau des perfs..
0
Rejoignez-nous