Read multiple text files using System.IO and Visual C# . NET and writing to these files

Asked

Viewed 799 times

0

My problem is this. I have several . txt files in a pc directory. These files have information on each line and have blank lines.

What I would need to do is read all the files in the directory, open them one by one, read the information in each, and add a numerical index in each, followed by a semicolon and erasing the blank or spaced lines.

Voilà, I got it partially.

My program reads the directory, lists the files, opens and reads the information in them, but when it goes to record the information, it replicates the information from the first file in the second.

Ex.: If in a file I have the provision

joao
legal

the result in the first file is

0;joao
1;legal

in the second file I have the information:

marcelo
medeiros

but, after running the program, the result in the second file is:

0;joao
1;legal
2;marcelo
3;medeiros

So, if there are many and many files, you can imagine what the final file would look like.

Can someone help me find where the bug in my program is?

Follows the code:

static void Main(string[] args)
{
    List<string> lines = new List<string>();

    string path3;
    int counter = 0;


    path3 = @"C:\Users\msant\Desktop\New folder\";

    string[] files = Directory.GetFiles(path3);

    foreach (var file in files)
    {

        if (File.Exists(file))
        {
            try
            {
                //ABRE E LÊ O ARQUIVO TXT

                using (StreamReader reader = new StreamReader(file))
                {
                    while (!reader.EndOfStream)
                    {

                        string line = reader.ReadLine();

                        if (!string.IsNullOrWhiteSpace(line))
                        {
                            var lineOutput = counter++ + ";";
                            lines.Add(lineOutput + line);
                        }

                    }
                    reader.Close();
                    reader.Dispose();
                }

                foreach (var line in lines)
                {

                    Console.WriteLine(line);
                }


                //ESCREVE NOS ARQUIVOS TXT

                using (StreamWriter writer = new StreamWriter(file))
                {
                    foreach (var item in lines)
                    {
                        writer.WriteLine(item);
                    }

                    writer.Close();
                }


            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.ReadKey();
            }
        }

        else
        {
            Console.WriteLine("ALERTA: O ARQUIVO LOCALIZADO EM <-- " + path3+ " --> NAO EXISTE.");
        }


        Console.ReadKey();
    }
}

2 answers

2

Like Victor said, the problem is you’re not clearing the list.

Other than that, another code option:

static void Main(string[] args)
{
    string path = @"D:\Teste\";

    string[] files = Directory.GetFiles(path,"*.txt", SearchOption.TopDirectoryOnly);
    List<string> valores = new List<string>();
    foreach (string file in files)
    {
        Console.WriteLine($"Processando arquivo {file}");
        string[] linhas = File.ReadAllLines(file);
        foreach (string linha in linhas)
            if (!String.IsNullOrEmpty(linha))
                valores.Add(linha);


        using (TextWriter tw = new StreamWriter(file, false, Encoding.Default))
        {
            for (int i =0; i< valores.Count; i++)
            {
                tw.WriteLine($"{i};{valores[i]}");
            }
        }

        valores.Clear();

    }

    Console.ReadKey();

}

1


So, first of all you wouldn’t need to declare Dispose() inside your block usingbecause the use of using allows classes that implement Idisposable are used in such a way as to ensure the execution of the method Dispose() at the end of its use, even if an exception is made.

He is writing everything again in the second file because its variable Lines is out of your for causing it not to be initialized again with each repetition per file, so when writing the file it is with the previous values.

You can play the initialization of it inside the for making every repetition it is cleaned again:

static void Main(string[] args)
    {
        string path3;
        int counter = 0;


        path3 = @"C:\Users\msant\Desktop\New folder\";

        string[] files = Directory.GetFiles(path3);

        foreach (var file in files)
        {
            List<string> lines = new List<string>();

            if (File.Exists(file))
            {
                try
                {
                    //ABRE E LÊ O ARQUIVO TXT

                    using (StreamReader reader = new StreamReader(file))
                    {
                        while (!reader.EndOfStream)
                        {

                            string line = reader.ReadLine();

                            if (!string.IsNullOrWhiteSpace(line))
                            {
                                var lineOutput = counter++ + ";";
                                lines.Add(lineOutput + line);
                            }

                        }
                        reader.Close();
                    }

                    foreach (var line in lines)
                    {

                        Console.WriteLine(line);
                    }


                    //ESCREVE NOS ARQUIVOS TXT

                    using (StreamWriter writer = new StreamWriter(file))
                    {
                        foreach (var item in lines)
                        {
                            writer.WriteLine(item);
                        }

                        writer.Close();
                    }


                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.ReadKey();
                }
            }

            else
            {
                Console.WriteLine("ALERTA: O ARQUIVO LOCALIZADO EM <-- " + path3+ " --> NAO EXISTE.");
            }


            Console.ReadKey();
        }
    }

  • Thank you for the reply! ;)

  • 1

    Just an addendum in the code, if I just transfer the Ines into the is, it only takes the first file. I changed it like this: before if(File.Exists) I declared again the variable Lines: Lines = new List<string>(); and the counter again at 0 - counter = 0; - otherwise it will follow the index and will number all the files in sequence. Valeu Victor!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.