Souci avec ReadLine (StreamReader) [Résolu]

el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 24 août 2005 à 11:15 - Dernière réponse : Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention
- 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
Afficher la suite 

20 réponses

Répondre au sujet
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 24 août 2005 à 18:35
+3
Utile
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( );
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Lutinore
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 25 août 2005 à 10:35
+3
Utile
décidément... "^milieu.*$"


<HR>
Sébastien FERRAND

Blog :
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de sebmafate
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 25 août 2005 à 10:46
+3
Utile
essaye celle-ci : "^milieu.*$"

Sébastien FERRAND
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de sebmafate
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 24 août 2005 à 11:16
0
Utile
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 :-)
Commenter la réponse de el_teedee
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 24 août 2005 à 11:28
0
Utile
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
Commenter la réponse de sebmafate
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 24 août 2005 à 11:31
0
Utile
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
Commenter la réponse de el_teedee
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 24 août 2005 à 11:36
0
Utile
Apparemment, c'est une sorte de masque ? Si tu veux bien me montrer ce que ca donnerait dans mon cas, je suis preneur...
Commenter la réponse de el_teedee
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 24 août 2005 à 11:54
0
Utile
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
Commenter la réponse de sebmafate
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 25 août 2005 à 10:16
0
Utile
>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.
Commenter la réponse de el_teedee
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 25 août 2005 à 10:26
0
Utile
je me suis trompé dans l'expression régulière

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

Sébastien FERRAND
Commenter la réponse de sebmafate
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 25 août 2005 à 10:40
0
Utile
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 ?
Commenter la réponse de el_teedee
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 25 août 2005 à 10:41
0
Utile
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*$"
Commenter la réponse de el_teedee
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 25 août 2005 à 10:45
0
Utile
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 ?
Commenter la réponse de el_teedee
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 25 août 2005 à 10:48
0
Utile
c'est possible... dans ce cas, sur ta chaine fait un .Replace("\n","\r\n")

Sébastien FERRAND
Commenter la réponse de sebmafate
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 25 août 2005 à 11:35
0
Utile
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...
Commenter la réponse de el_teedee
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 25 août 2005 à 11:41
0
Utile
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;

}

}

}
Commenter la réponse de el_teedee
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 25 août 2005 à 12:08
0
Utile
Merci pour ces precisions.

Sébastien FERRAND
Commenter la réponse de sebmafate
el_teedee 498 Messages postés mercredi 7 juillet 2004Date d'inscription 13 juillet 2015 Dernière intervention - 25 août 2005 à 13:39
0
Utile
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) ?
Commenter la réponse de el_teedee
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 25 août 2005 à 13:51
0
Utile
Utilise un StringBuilder, dans System.Text.

Sébastien FERRAND
Commenter la réponse de sebmafate
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 25 août 2005 à 15:35
0
Utile
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..
Commenter la réponse de Lutinore

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.