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

Signaler
Messages postés
36
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mars 2010
-
Messages postés
36
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mars 2010
-
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

Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
84
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
*/
Messages postés
36
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mars 2010

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.
Messages postés
36
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mars 2010

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.
Messages postés
47
Date d'inscription
lundi 14 septembre 2009
Statut
Membre
Dernière intervention
6 novembre 2009
2
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 ^^'
Messages postés
36
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mars 2010

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.
Messages postés
36
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mars 2010

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...
Messages postés
47
Date d'inscription
lundi 14 septembre 2009
Statut
Membre
Dernière intervention
6 novembre 2009
2
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();

            }

Messages postés
47
Date d'inscription
lundi 14 septembre 2009
Statut
Membre
Dernière intervention
6 novembre 2009
2
Bon,

En fait j'ai pas assez de temps la,

Je regarde ce soir ^^'
Messages postés
36
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mars 2010

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.
Messages postés
47
Date d'inscription
lundi 14 septembre 2009
Statut
Membre
Dernière intervention
6 novembre 2009
2
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 :)
Messages postés
36
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mars 2010

Maintenant ça fonctionne parfaitement, merci DrIvory.