我试图用c#语言一行一行地写入csv文件。这是我的函数

string first = reader[0].ToString();
string second=image.ToString();
string csv = string.Format("{0},{1}\n", first, second);
File.WriteAllText(filePath, csv);

整个函数在循环中运行,每一行都应该写入csv文件。在我的例子中,下一行覆盖了现有的行,最后,我在csv文件中只得到一条记录,这是最后一条记录。如何写入csv文件中的所有行?


当前回答

我强烈建议你走更乏味的路线。尤其是当你的文件很大的时候。

using(var w = new StreamWriter(path))
{
    for( /* your loop */)
    {
        var first = yourFnToGetFirst();
        var second = yourFnToGetSecond();
        var line = string.Format("{0},{1}", first, second);
        w.WriteLine(line);
        w.Flush();
    }
}

file. appendalltext()打开一个新文件,写入内容,然后关闭文件。与将数据写入开放流相比,打开文件是一个耗费大量资源的操作。在循环中打开/关闭文件会导致性能下降。

Johan建议的方法解决了这个问题,方法是将所有输出存储在内存中,然后只写入一次。然而(在大文件的情况下),您的程序将消耗大量的RAM,甚至崩溃与OutOfMemoryException

我的解决方案的另一个优点是,您可以通过保存输入数据中的当前位置来实现暂停/恢复。

乌利希期刊指南。把使用放在正确的地方

其他回答

下面是另一个开源库,可以轻松创建CSV文件,Cinchoo ETL

List<dynamic> objs = new List<dynamic>();

dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = @"Mark";
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
rec1.Salary = new ChoCurrency(100000);
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Tom";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
rec2.Salary = new ChoCurrency(150000);
objs.Add(rec2);

using (var parser = new ChoCSVWriter("emp.csv").WithFirstLineHeader())
{
    parser.Write(objs);
}

有关更多信息,请阅读CodeProject关于使用的文章。

你可能只需要添加换行符“\n\r”。

而不是每次调用AppendAllText(),你可以考虑打开文件一次,然后写整个内容一次:

var file = @"C:\myOutput.csv";

using (var stream = File.CreateText(file))
{
    for (int i = 0; i < reader.Count(); i++)
    {
        string first = reader[i].ToString();
        string second = image.ToString();
        string csvRow = string.Format("{0},{1}", first, second);

        stream.WriteLine(csvRow);
    }
}
enter code here

string string_value= string. empty;

        for (int i = 0; i < ur_grid.Rows.Count; i++)
        {
            for (int j = 0; j < ur_grid.Rows[i].Cells.Count; j++)
            {
                if (!string.IsNullOrEmpty(ur_grid.Rows[i].Cells[j].Text.ToString()))
                {
                    if (j > 0)
                        string_value= string_value+ "," + ur_grid.Rows[i].Cells[j].Text.ToString();
                    else
                    {
                        if (string.IsNullOrEmpty(string_value))
                            string_value= ur_grid.Rows[i].Cells[j].Text.ToString();
                        else
                            string_value= string_value+ Environment.NewLine + ur_grid.Rows[i].Cells[j].Text.ToString();
                    }
                }
            }
        }


        string where_to_save_file = @"d:\location\Files\sample.csv";
        File.WriteAllText(where_to_save_file, string_value);

        string server_path = "/site/Files/sample.csv";
        Response.ContentType = ContentType;
        Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(server_path));
        Response.WriteFile(server_path);
        Response.End();

更新

回到我的naïve时代,我建议手动做这件事(这是一个简单问题的简单解决方案),然而由于这变得越来越流行,我建议使用库CsvHelper来做所有的安全检查,等等。

CSV比问题/答案所暗示的要复杂得多。

原来的答案

因为你已经有了一个循环,考虑这样做:

//before your loop
    var csv = new StringBuilder();

//in your loop
    var first = reader[0].ToString();
    var second = image.ToString();
    //Suggestion made by KyleMit
    var newLine = string.Format("{0},{1}", first, second);
    csv.AppendLine(newLine);  

//after your loop
    File.WriteAllText(filePath, csv.ToString());

或者类似的东西。 我的理由是:你不需要为每一项写入文件,你只需要打开流一次,然后写入它。

你可以替换

File.WriteAllText(filePath, csv.ToString());

File.AppendAllText(filePath, csv.ToString());

如果您希望将CSV的以前版本保存在同一文件中

C# 6

如果您正在使用c# 6.0,那么您可以执行以下操作

var newLine = $"{first},{second}"

EDIT

这里有一个问题的链接,解释了什么环境。换行符。