[C#] Lire et écrire dans un fichier txt

cs_Krasha Messages postés 36 Date d'inscription mardi 25 septembre 2007 Statut Membre Dernière intervention 29 mars 2010 - 21 sept. 2009 à 23:48
cs_Krasha Messages postés 36 Date d'inscription mardi 25 septembre 2007 Statut Membre Dernière intervention 29 mars 2010 - 25 sept. 2009 à 19:24
Bonjour à tous,

Je suis actuellement en train d'apprendre le C# en lisant quelques tutos, et cours en pdf. Je découvre donc petit à petit les ficelles de la programmation, mais c'est pas toujours simple.

Donc voilà: Dans mon projet j'ai un dossier 'DataCapital' qui contient plusieurs fichiers txt. Je souhaiterais lire, un à un, ces fichiers et en retirer quelques valeurs pour les copiers dans un fichier créé pour l'occasion.

Les valeurs a récupérer ont toutes des points communs, ce qui me facilitera le travail je pense. Par contre j'ai des soucis avec le travail sur les fichiers.

J'arrive à lire le fichier ligne après ligne, éventuellement même à repérer la valeur qui m'intéresse, mais je ne sais pas comment l'extraire pour l'écrire dans un fichier prévu à cet effet (nommons le ExtractData.txt).

Pourriez vous me preter main forte? Sans forcément me donner la réponse, au moins m'indiquer quelles procédures utiliser.

Voici mon code, les boucles pour enchainer les fichiers les uns après les autres ne sont pas présentes, puisque inutiles pour l'instant.

static void Main(string[] args)
     {
//boolean pour vérifier l'existance du dossier DataCapital
         bool blDosExist = false;
//boolean pour vérifier l'existance des fichiers txt   
         bool blFichExist = false;  
// déclaration de la liste TabProdTxt
         string[] TabProdTxt;    
         int index 0, intTestFichExist 0, intIndexFich = 0;

// création de la liste TabProdTxt contenant les noms des fichiers txt
         TabProdTxt = new string[10] ; 

// test de la présence du dossier DataCapital 
         blDosExist = Directory.Exists("DataCapital");
         if (blDosExist == false)
         {
// Message d'erreur en cas de dossier introuvable
             Console.WriteLine("Erreur, le dossier 'DataCapital' est introuvable");
             Console.ReadLine();
         }

//Les noms des fichiers contenus dans le dossier "DataCapital" 
//deviennent les valeurs des postes du tableau TabProdTxt
         TabProdTxt = Directory.GetFiles("DataCapital");
         Console.ReadLine();

//Regex pour trouver la valeur qui nous intéresse dans les fichiers
         Regex RecupData = new Regex("^Informations de fabrication+$");
//Instance de lecture avec possibilité de lire les accents
         StreamReader testLec = new StreamReader(TabProdTxt[0], ASCIIEncoding.Default);
         String strLine = testLec.ReadLine();// Lecture première ligne

         while ((strLine !null) & (RecupData.IsMatch(strLine) false))
         {
                
             testLec.ReadLine();
         }
     }


Apparemment StreamReader permet de lire mais pas d'écrire, alors que StreamWriter permet d'écrire mais pas de lire. Donc comment lire dans un fichier, en extraire des données et ensuite les écrire dans un autre fichier ('ExtractData.txt') ?

Merci pour vos lumières

11 réponses

cs_coq Messages postés 6350 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
22 sept. 2009 à 00:09
Bonjour,

Justement, la réponse est dans la question : "Apparemment StreamReader permet de lire mais pas d'écrire, alors que StreamWriter permet d'écrire mais pas de lire"
Dans les grandes lignes, il suffit d'utiliser une instance de StreamReader pour lire le fichier source et une instance de StreamWriter pour écrire dans le fichier cible.


/*
coq
MVP Visual C#
CoqBlog
*/
0
cs_Krasha Messages postés 36 Date d'inscription mardi 25 septembre 2007 Statut Membre Dernière intervention 29 mars 2010
22 sept. 2009 à 00:12
Ok mais comment j'extraie les valeurs en question? Parce que "justement c'est dans la question", j'arrive à trouver les valeurs, je sais écrire dans un fichiers, mais je ne sais pas récupérer les valeurs de l'un pour les mettre dans l'autre. Voilà mon soucis.

Je pense que je vais finir par trouver, la nuit porte conseil. En tout cas merci à toi pour la rapidité de ta réponse cop.
0
cs_Krasha Messages postés 36 Date d'inscription mardi 25 septembre 2007 Statut Membre Dernière intervention 29 mars 2010
22 sept. 2009 à 08:45
Même après une bonne nuit de conseil, j'ai pas de solution.

Je me repencherais sur ce code après le boulot, bonne journée à tous.
0
DrIvory Messages postés 47 Date d'inscription lundi 14 septembre 2009 Statut Membre Dernière intervention 6 novembre 2009 3
22 sept. 2009 à 12:46
Bah pour recup ton info,
tu peux faire quelque chose du genre:
StreamWriter writer = new StreamWriter("out.txt"); 
while ((strLine !null) & (RecupData.IsMatch(strLine) false))
{
   if (RecupData.IsMatch(strLine))
   {
     MatchCollection res = RecupData.Matches(strLine);
                
     for (int i = 0; i < res.Count; i++)
         writer.WriteLine(res[i].Value);
   }

   testLec.ReadLine();
}
writer.Close();


En espérant que ca t'aide ^^'
0

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

Posez votre question
cs_Krasha Messages postés 36 Date d'inscription mardi 25 septembre 2007 Statut Membre Dernière intervention 29 mars 2010
23 sept. 2009 à 15:24
J'ai testé ta prpoposition, ça à l'air de fonction effectivement. Je te remercie donc pour ce coup de main.

Je dois quand même attendre d'être à la maison pour vérifier avec les données. Mais je pense que nous sommes sur la bonne voie.
0
cs_Krasha Messages postés 36 Date d'inscription mardi 25 septembre 2007 Statut Membre Dernière intervention 29 mars 2010
23 sept. 2009 à 16:04
Hum... après l'avoir passé au debugger je vois quand même un soucis.

while ((strLine !null) & (RecupData.IsMatch(strLine) false))
            {
                if (RecupData.IsMatch(strLine))
                {
                    MatchCollection res = RecupData.Matches(strLine);
                    for (int i = 0; i < res.Count; i++)
                        writer.WriteLine(res[i].Value);
                }
                testLec.ReadLine();
            }
            writer.Close();


En fait si je regarde bien les instructions, on dit:
Tant que ('Ma ligne' n'est pas vide) ET (que ma recherche est infructueuse) mais la boucle ne change jamais de ligne, donc elle tourne en rond.

Dans le debugger on voit bien que seule la première ligne est lue.

Je te poste mon code en entier si tu veux vérifier par toi même (ou qui que se soit d'autre) biensur il te faudra créé un dossier 'DataCapital' (à placer ici : \Mes documents\Visual Studio 2008\Projects\TransformCapital\TransformCapital\bin\Debug ) et mettre quelques fichiers dedans.

Voilà :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace TransformCapital
{
    class Program
    {
        static void Main(string[] args)
        {
            bool blDosExist = false;  //boolean pour vérifier l'existance du dossier DataCapital 
            string[] TabProdTxt;    // déclaration de la liste TabProdTxt
            int finFichier = 0;
            


            // création de la liste TabProdTxt contenant les noms des fichiers txt
            TabProdTxt = new string[10]; 

            // test de la présence du dossier DataCapital 
            blDosExist = Directory.Exists("DataCapital");
            if (blDosExist == false)
            {
                Console.WriteLine("Erreur, le dossier 'DataCapital' est introuvable");
                Console.ReadLine();
            }else Console.WriteLine("ouverture du dossier \'DataCapital\'...");

            TabProdTxt = Directory.GetFiles("DataCapital");
            Console.WriteLine("chargement de la liste des fichiers...");
            Console.ReadLine();

            //Instance de lecture avec possibilité de lire les accents
            Regex RecupData = new Regex("Informations de fabrication");
            StreamReader testLec = new StreamReader(TabProdTxt[0], ASCIIEncoding.Default);
            String strLine = testLec.ReadLine();// Lecture première ligne

            if (strLine == null)
            {
                finFichier++;
            }

            StreamWriter writer = new StreamWriter("out.txt");
            while ((finFichier <3) & (RecupData.IsMatch(strLine) false))
            {
                if (RecupData.IsMatch(strLine))
                {
                    MatchCollection res = RecupData.Matches(strLine);
                    for (int i = 0; i < res.Count; i++)
                        writer.WriteLine(res[i].Value);
                }
                testLec.ReadLine();
            }
            writer.Close();
        }
    }
}


Si vous voyez ce qui cloche...
0
DrIvory Messages postés 47 Date d'inscription lundi 14 septembre 2009 Statut Membre Dernière intervention 6 novembre 2009 3
23 sept. 2009 à 16:08
En faite,

j'avais mal lu mais vire:
(RecupData.IsMatch(strLine) == false)


et met plutot
while ((finFichier <= 3))

            {

                if (RecupData.IsMatch(strLine))

                {

                    MatchCollection res = RecupData.Matches(strLine);

                    for (int i = 0; i < res.Count; i++)

                        writer.WriteLine(res[i].Value);

                }

                testLec.ReadLine();

            }

0
DrIvory Messages postés 47 Date d'inscription lundi 14 septembre 2009 Statut Membre Dernière intervention 6 novembre 2009 3
23 sept. 2009 à 16:10
Bon,

En fait j'ai pas assez de temps la,

Je regarde ce soir ^^'
0
cs_Krasha Messages postés 36 Date d'inscription mardi 25 septembre 2007 Statut Membre Dernière intervention 29 mars 2010
23 sept. 2009 à 21:21
On se rapproche! C'est presque gagné!

Après quelques modifs voilà ce que ça donne (merci au passage à notre ami le débugger) :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace TransformCapital
{
    class Program
    {
        static void Main(string[] args)
        {
            bool blDosExist =   false;  //boolean pour vérifier l'existance du dossier DataCapital 
            string[] TabProdTxt;    // déclaration de la liste TabProdTxt
            //int finFichier = 0;



            // création de la liste TabProdTxt contenant les noms des fichiers txt
            TabProdTxt = new string[10];

            // test de la présence du dossier DataCapital 
            blDosExist = Directory.Exists("DataCapital");
            if (blDosExist == false)
            {
                Console.WriteLine("Erreur, le dossier 'DataCapital' est introuvable");
                Console.ReadLine();
            }
            else Console.WriteLine("ouverture du dossier \'DataCapital\'...");

            TabProdTxt = Directory.GetFiles("DataCapital");
            Console.WriteLine("chargement de la liste des fichiers...");
            Console.ReadLine();

            //Instance de lecture avec possibilité de lire les accents
            Regex RecupData = new Regex("Informations de fabrication
 (.+) (.+)
(.+) (.+) 
(.+)(.+)
(.+)(.+)
(.+)(.+)
(.+)(.+)
(.+)(.+)

<hr><center>");
            StreamReader testLec   = new StreamReader(TabProdTxt[0], ASCIIEncoding.Default);
            String strLine = testLec.ReadLine();// Lecture première ligne


            StreamWriter writer = new StreamWriter("out.txt");
            
            //... essai code
            string str = testLec.ReadLine();
            while (str != null)
            {
                /*while (finFichier <= 3)
                {
                    if (strLine == "")
                    {
                        finFichier++;
                    }*/
                    if (RecupData.IsMatch(str))
                    {
                        MatchCollection res = RecupData.Matches(str);
                        for (int i = 0; i < res.Count; i++)
                        {
                            writer.WriteLine(res[i].Value);
                        }
                    }
                    
                //}
                str = testLec.ReadLine();
            }
            
            writer.Close();
        }
    }
}


Maintenant je ne bloque plus sur les lignes vides grace à
while (str != null)

J'arrive à récupérer la ligne qui m'intéresse et à l'écrire dans le fichier "out.txt" par contre je ne sais pas comment récupérer que les (.+) de ma regex (avec cette histoire de (.+) à récupérer avec $1 ).

Regex RecupData = new Regex("Informations de fabrication
(.+)(.+)
(.+)(.+)
(.+)(.+)
(.+)(.+)
(.+)(.+)
(.+)(.+)
(.+)(.+)

<hr><center>");


J'ai pas encore bien saisit comment ça fonctionne pour ne garder QUE les données représentées par (.+) et virer le reste avant de copier le résultat dans "out.txt"

Mais ça avance bien! Merci à toi, tu m'as vraiment permis de continuer ce petit programme sur lequel j'étais complètement bloqué.

ps: par contre quand je lance le programme sur un autre fichier txt le résultat écrase ce qui était déjà inscrit dans "out.txt" j'ai dû loupé une option pour que le prog écrive sur la ligne suivante au lieu d'effacer les anciennes extractions.
0
DrIvory Messages postés 47 Date d'inscription lundi 14 septembre 2009 Statut Membre Dernière intervention 6 novembre 2009 3
24 sept. 2009 à 09:53
Déjà pour pouvoir écrire à la suite de ton fichier,
remplace:
StreamWriter writer = new StreamWriter("out.txt");

par:
StreamWriter writer = new StreamWriter("out.txt", true);


Pour ta Regex bon courage :)
0
cs_Krasha Messages postés 36 Date d'inscription mardi 25 septembre 2007 Statut Membre Dernière intervention 29 mars 2010
25 sept. 2009 à 19:24
Maintenant ça fonctionne parfaitement, merci DrIvory.
0
Rejoignez-nous