4est
4est

Reputation: 3168

Improve saving to CSV file (C#)

I'm writing column data to CSV file:

string sep = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
string csvFile = "MyName.csv";

using (StreamWriter writer = new StreamWriter(csvFile))
{
    var newLine = new StringBuilder();

    foreach (int item in someTable)
    {
        string x = (string)dt.DataTable.Rows[item].Value("abc");
        newLine.Append(x);
        newLine.Append(sep);

        string x2 = (string)dt.DataTable.Rows[item].Value("abc2");
        newLine.Append(x2);
        newLine.Append(sep);

        string x3 = (string)dt.DataTable.Rows[item].Value("abc3");
        newLine.Append(x3);
        newLine.Append(sep);

        int x4 = (int)dt.DataTable.Rows[item].Value("abc4");
        newLine.Append(x4);
        newLine.Append(sep);

        //....and more data to Append - around 20
        ...
        writer.WriteLine(newLine);
        newLine.Clear();
    }
    writer.Flush();
    writer.Close();
}

It's possible to not easier and not always repeat newLine.Append(sep); ? Or maybe other improvements?

Upvotes: 1

Views: 431

Answers (2)

MarkPflug
MarkPflug

Reputation: 29538

I maintain a library, Sylvan.Data.Csv that makes this quite easy to accomplish. It handles the complexities of escaping delimiters and quotes, when necessary, which the naive implementations presented in other answers do not.

Here is an example implementation of an extension method using my library that would allow you to write dataTable.SaveAsCsv("myfile.csv");.

public static void SaveAsCsv(this DataTable dt, string filename)
{
  using var csvWriter = Sylvan.Data.Csv.CsvDataWriter.Create(filename);
  csvWriter.Write(dt.CreateDataReader());
}

My library is also the fastest CSV writer (and reader) for .NET, at least according to my benchmarks. It is even faster than the naive implementation.

Upvotes: 0

frankM_DN
frankM_DN

Reputation: 371

One potential idea would be to create a variable to represent the row such as

var row = dt.DataTable.Rows[item]; and also create a list or array to hold all of the column names, something like

string[] cols = {"abc", "abc2", "abc3"}; then inside of your current foreach loop you could do the following:

foreach (string colName in cols)
{
     newLine.Append((string)row.Value(colName));
     newLine.Append(sep);
}
writer.WriteLine(newLine);
newLine.Clear();

Upvotes: 1

Related Questions