241

csvC# 言語を使用して行ごとにファイルに書き込もうとしています。これが私の機能です

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

関数全体がループ内で実行され、すべての行がファイルに書き込まれcsvます。私の場合、次の行は既存の行を上書きし、最終的に、csv ファイルで最後のレコードを 1 つだけ取得しています。ファイルにすべての行を書き込むにはどうすればよいcsvですか?

4

15 に答える 15

368

アップデート

私の素朴な時代に戻って、これを手動で行うことを提案しました (単純な質問に対する単純な解決策でした) が、これがますます普及しているため、すべての安全性チェックなど を行うライブラリ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}"

編集

これは、何が機能するかを説明する質問へのリンクEnvironment.NewLineです。

于 2013-09-12T06:47:49.040 に答える
101

もっと退屈な道を行くことを強くお勧めします。特にファイルサイズが大きい場合。

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

私のソリューションのもう1つの利点は、入力データに現在の位置を保存することで一時停止/再開を実装できることです。

更新。適切な場所に配置して使用する

于 2013-09-12T06:52:53.283 に答える
14

毎回呼び出す代わりにAppendAllText()、ファイルを 1 回開いてからコンテンツ全体を 1 回書き込むことを考えることができます。

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);
    }
}
于 2013-09-12T07:09:17.223 に答える
6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;

public partial class CS : System.Web.UI.Page
{
    protected void ExportCSV(object sender, EventArgs e)
    {
        string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
        using (SqlConnection con = new SqlConnection(constr))
        {
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM Customers"))
            {
                using (SqlDataAdapter sda = new SqlDataAdapter())
                {
                    cmd.Connection = con;
                    sda.SelectCommand = cmd;
                    using (DataTable dt = new DataTable())
                    {
                        sda.Fill(dt);

                        //Build the CSV file data as a Comma separated string.
                        string csv = string.Empty;

                        foreach (DataColumn column in dt.Columns)
                        {
                            //Add the Header row for CSV file.
                            csv += column.ColumnName + ',';
                        }

                        //Add new line.
                        csv += "\r\n";

                        foreach (DataRow row in dt.Rows)
                        {
                            foreach (DataColumn column in dt.Columns)
                            {
                                //Add the Data rows.
                                csv += row[column.ColumnName].ToString().Replace(",", ";") + ',';
                            }

                            //Add new line.
                            csv += "\r\n";
                        }

                        //Download the CSV file.
                        Response.Clear();
                        Response.Buffer = true;
                        Response.AddHeader("content-disposition", "attachment;filename=SqlExport.csv");
                        Response.Charset = "";
                        Response.ContentType = "application/text";
                        Response.Output.Write(csv);
                        Response.Flush();
                        Response.End();
                    }
                }
            }
        }
    }
}
于 2016-03-26T04:45:50.950 に答える
3

カンマの処理

を使用するときに値内のコンマを処理するstring.Format(...)ために、次のことがうまくいきました:

var newLine = string.Format("\"{0}\",\"{1}\",\"{2}\"",
                              first,
                              second,
                              third                                    
                              );
csv.AppendLine(newLine);

したがって、ヨハンの答えと組み合わせると、次のようになります。

//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());

CSV ファイルを返す

ファイルを特定の場所に書き込むのではなく、単純にファイルを返したい場合は、次の例を参考にしてください。

ストアド プロシージャから

public FileContentResults DownloadCSV()
{
  // I have a stored procedure that queries the information I need
  SqlConnection thisConnection = new SqlConnection("Data Source=sv12sql;User ID=UI_Readonly;Password=SuperSecure;Initial Catalog=DB_Name;Integrated Security=false");
  SqlCommand queryCommand = new SqlCommand("spc_GetInfoINeed", thisConnection);
  queryCommand.CommandType = CommandType.StoredProcedure;

  StringBuilder sbRtn = new StringBuilder();

  // If you want headers for your file
  var header = string.Format("\"{0}\",\"{1}\",\"{2}\"",
                             "Name",
                             "Address",
                             "Phone Number"
                            );
  sbRtn.AppendLine(header);

  // Open Database Connection
  thisConnection.Open();
  using (SqlDataReader rdr = queryCommand.ExecuteReader())
  {
    while (rdr.Read())
    {
      // rdr["COLUMN NAME"].ToString();
      var queryResults = string.Format("\"{0}\",\"{1}\",\"{2}\"",
                                        rdr["Name"].ToString(),
                                        rdr["Address"}.ToString(),
                                        rdr["Phone Number"].ToString()
                                       );
      sbRtn.AppendLine(queryResults);
    }
  }
  thisConnection.Close();

  return File(new System.Text.UTF8Encoding().GetBytes(sbRtn.ToString()), "text/csv", "FileName.csv");
}

リストから

/* To help illustrate */
public static List<Person> list = new List<Person>();

/* To help illustrate */
public class Person
{
  public string name;
  public string address;
  public string phoneNumber;
}

/* The important part */
public FileContentResults DownloadCSV()
{
  StringBuilder sbRtn = new StringBuilder();

  // If you want headers for your file
  var header = string.Format("\"{0}\",\"{1}\",\"{2}\"",
                             "Name",
                             "Address",
                             "Phone Number"
                            );
  sbRtn.AppendLine(header);

  foreach (var item in list)
  {
      var listResults = string.Format("\"{0}\",\"{1}\",\"{2}\"",
                                        item.name,
                                        item.address,
                                        item.phoneNumber
                                       );
      sbRtn.AppendLine(listResults);
    }
  }

  return File(new System.Text.UTF8Encoding().GetBytes(sbRtn.ToString()), "text/csv", "FileName.csv");
}

うまくいけば、これは役に立ちます。

于 2016-09-16T16:06:39.063 に答える
0

改行を追加する必要があるかもしれません"\n\r"

于 2015-06-21T12:38:25.720 に答える
0

これは、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の記事を参照してください。

于 2017-10-03T22:04:43.043 に答える