Home > Software design >  Not able write list of values line by line in a csv file
Not able write list of values line by line in a csv file

Time:12-16

Here i am reading a csv file line by line(to update and append some values) and convert into a list. While again trying to write a csv file from the list,I'm unable to write it line by line.

Actual Format:

1  abc 76-8 3 sht 09-9 5 bry 77-0

Expected Format:

 1 abc 76-8
 3 sht 09-9
 5 bry 77-0

Here is my code:

using (var reader = new StreamReader(@"D:FileWatcher/File_A.csv"))
{  
    List<string> fulllist = File.ReadAllLines(@"D:FileWatcher/File_A.csv").ToList();
    foreach(var item in fulllist)
    {
        var line = reader.ReadLine();
        var values = line.Split(',').ToList();
        var Col1Value = values[0].Substring(8,2);
        var Col0Value = values[0].Substring(0,7);

        values.RemoveAt(0);

        values.Insert(0, Col1Value);
        values.Insert(0, Col0Value);
        
        string combinedString = string.Join(",", values);

        var PathforFileB = @"D:FileWatcher/Result/File_B.csv";

        File.WriteAllText(PathforFileB, combinedString);
    }
}

CodePudding user response:

There are some problems in the code you posted.
There is no need to use a StreamReader if you plan to user ReadAllLines. Even better is to avoid ReadAllLines because that method loads everything in memory creating a potentially very large array of strings. Instead there is a ReadLines method that "enumerates" the lines one by one and is usable directly in a foreach loop.

Then your main problem is how you write the elaborated line back to file. The call to WriteAllText is inside the loop, but WriteAllText overwrites the file if it exists. So at each loop the code rewrites the file with the current line values. And WriteAllText doesn't add for you a newline at the end of the output. So just use a StreamWriter and output with WriteLine.

So let's change the original code in this way

using var writer = new StreamWriter(@"D:FileWatcher/File_B.csv");
foreach (var item in File.ReadLines(@"D:FileWatcher/File_A.csv"))
{
    var values = item.Split(' ');
    var firstLine = string.Join(' ', values[0], values[1], values[2]);
    var secondLine = string.Join(' ', values[3], values[4], values[5]);
    var thirdLine = string.Join(' ', values[6], values[7], values[8]);
    writer.WriteLine(firstLine);
    writer.WriteLine(secondLine);
    writer.WriteLine(thirdLine);
}

The code now starts creating the output file, then reads line by line the input file and splits the line in its 9 words. Finally it rebuilds 3 substrings with the splitted words array. Finally writes everything in the output file.

Of course you should be absolutely certain that each line in the input file can be splitted at the space and produces at least 9 substrings. If this is not the case you need to add some error checks and resolve the invalid line according to your logic.

CodePudding user response:

The main problem in the original code is it re-opened the file at the beginner on every loop iteration. You can help a lot by changing File.WriteAllText() to File.AppendAllText() and including a line feed as part of the strings. But even then it was a lot less efficient and more complicated than it needed to be.

var data = File.ReadLines(@"D:\FileWatcher\File_A.csv").
    Select(line => line.Split(',')).
    Select(line => $"{line[0].Substring(8,2)}, {line[0].Substring(0, 7)}, {string.Join(",", line.Skip(1))}");

File.WriteAllLines(@"D:FileWatcher\Result\File_B.csv", data);
  • Related