Search code examples
c#csvstreamwriter

StreamWriter only writes one line


I am trying to write from a .csv file to a new file.

Every time StreamWriter writes, it writes to the first line of the new file. It then overwrites that line with the next string, and continues to do so until StreamReader reaches EndOfStream.
Has anybody ever experienced this? How did you overcome it?

This is my first solution outside of those required in by my school work. There is an unknown number of rows in the original file. Each row of the .csv file has only 17 columns. I need to write only three of them and in the order found in the code snippet below.
Before coding the StreamWriter I used Console.WriteLine() to make sure that each line was in the correct order.

Here is the code snippet:

{
    string path = @ "c:\directory\file.csv";
    string newPath = @ "c:\directory\newFile.csv"

    using(FileStream fs = new FileStream(path, FileMode.Open))
    {
        using(StreamReader sr = new StreamReader(fs))
        {
            string line;
            string[] columns;
            while ((line = sr.ReadLine()) != null)
            {
                columns = line.Split(',');
                using(FileStream aFStream = new FileStream(
                    newPath, 
                    FileMode.OpenOrCreate, 
                    FileAccess.ReadWrite))
                using(StreamWriter sw = new StreamWriter(aFStream))
                {
                    sw.WriteLine(columns[13] + ',' + columns[10] + ',' + columns[16]);
                    sw.Flush();
                    sw.WriteLine(sw.NewLine);
                }
            }
        }
    }
}

Solution

  • To correctly fix your code, you'll want to structure more:

    public void CopyFileContentToLog()
    {
         var document = ReadByLine();
         WriteToFile(document);
    }
    
    public IEnumerable<string> ReadByLine()
    {
         string line;
         using(StreamReader reader = File.OpenText(...))
              while ((line = reader.ReadLine()) != null)
                  yield return line;
    }
    
    public void WriteToFile(IEnumerable<string> contents)
    {
         using(StreamWriter writer = new StreamWriter(...))
         {
              foreach(var line in contents)
                  writer.WriteLine(line);
    
              writer.Flush();
         }
    }
    

    You could obviously tailor and make it a bit more flexible. But this should demonstrate and resolve some of the issues you have with your loop and streams.