Search code examples
c#streamreader

Use two streamreaders at the same time for comparing and replacing columns and rows?


See, I'm coding a simple program to replace data in a CSV file.

What I need to replace is column 2 (parent) to set the name of the ID instead of ID, like this:

Original file:

ID    - PARENT - NAME
ID 1  -        - Name of ID 1
ID 2  -  ID 1  - Name of ID 2
ID 3  -  ID 2  - Name of ID 3
ID 4  -  ID 1  - Name of ID 4
ID 5  -  ID 4  - Name of ID 5

Result:

ID    - PARENT         - NAME
ID 1  -                - Name of ID 1
ID 2  -  Name of ID 1  - Name of ID 2
ID 3  -  Name of ID 2  - Name of ID 3
ID 4  -  Name of ID 1  - Name of ID 4
ID 5  -  Name of ID 4  - Name of ID 5

So I need to do a recursive loop here using two instances of the same StreamReader to compare each one. I'm not asking how to do the loop, but how to use two streamreaders at the same time, as I tried to do it by creating all the variables necessary but it seems C# won't accept that, and it just doesn't work, the data goes all blank... and doesn't give any errors either. How I can do it?

The part that works:

filePath = openFileDialog.FileName;
var fileStream = openFileDialog.OpenFile();
using (System.IO.StreamReader reader = new System.IO.StreamReader(fileStream, Encoding.GetEncoding("iso-8859-1")))
{
    fileContent = reader.ReadLine();
    int i = 1;
    using (System.IO.StreamWriter writer = new System.IO.StreamWriter(nomArxiu, false, Encoding.GetEncoding("iso-8859-1")))
   {
      while (fileContent != null)
          {
              /// code to replace stuff, works for one single row at a time, but not for multiple rows at the same time
          }
   }
writer.Flush();
writer.Close();
}

What I tried that doesn't work:

System.IO.StreamReader reader2 = reader; // create a copy of the reader object...

I want to have access to two independent stream readers of the same file, but it just doesn't work like this...


Solution

  • The problem you have with your code is that classes in C# are passed by reference, not by value.

    This means that this line:

    System.IO.StreamReader reader2 = reader;

    ...is not creating a new StreamReader as you had expected, but has created another reference to the same StreamReader with the same stream position.

    What you need to do is create a new StreamReader with a new FileStream like so:

    filePath = openFileDialog.FileName;
    var fileStream = openFileDialog.OpenFile();
    var secondFileStream = openFileDialog.OpenFile();
    using (System.IO.StreamReader reader = new System.IO.StreamReader(fileStream, Encoding.GetEncoding("iso-8859-1")))
    using (System.IO.StreamReader reader2 = new System.IO.StreamReader(secondFileStream, Encoding.GetEncoding("iso-8859-1")))
    {
        fileContent = reader.ReadLine();
        int i = 1;
        using (System.IO.StreamWriter writer = new System.IO.StreamWriter(nomArxiu, false, Encoding.GetEncoding("iso-8859-1")))
        {
            while (fileContent != null)
            {
                /// code to replace stuff, works for one single row at a time, but not for multiple rows at the same time
            }
        }
        writer.Flush();
        writer.Close();
    }
    

    I'm not sure of the functionality of running OpenFileDialog.OpenFile() twice, so if that doesn't work, try this:

    filePath = openFileDialog.FileName;
    using (FileStream fileStream = File.Open(openFileDialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
    using (FileStream secondFileStream = File.Open(openFileDialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
    using (System.IO.StreamReader reader = new System.IO.StreamReader(fileStream, Encoding.GetEncoding("iso-8859-1")))
    using (System.IO.StreamReader reader2 = new System.IO.StreamReader(secondFileStream, Encoding.GetEncoding("iso-8859-1")))
    {
        fileContent = reader.ReadLine();
        int i = 1;
        using (System.IO.StreamWriter writer = new System.IO.StreamWriter(nomArxiu, false, Encoding.GetEncoding("iso-8859-1")))
        {
            while (fileContent != null)
            {
                /// code to replace stuff, works for one single row at a time, but not for multiple rows at the same time
            }
        }
        writer.Flush();
        writer.Close();
    }