我试图csv使用C#语言逐行写入文件.这是我的功能
string first = reader[0].ToString();
string second=image.ToString();
string csv = string.Format("{0},{1}\n", first, second);
File.WriteAllText(filePath, csv);
Run Code Online (Sandbox Code Playgroud)
整个函数在循环内运行,每一行都应该写入csv文件.在我的情况下,下一行将覆盖现有行,最后,我在csv文件中获得了唯一一条记录,这是最后一行.如何写入csv文件中的所有行?
Joh*_*han 277
UPDATE
回到我天真的日子,我建议手动执行此操作(这是一个简单的问题的简单解决方案),但由于这变得越来越流行,我建议使用库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());
Run Code Online (Sandbox Code Playgroud)
或者是这种效果的东西.我的理由是:您不需要为每个项目写入文件,您只需打开一次流然后写入它.
你可以替换
File.WriteAllText(filePath, csv.ToString());
Run Code Online (Sandbox Code Playgroud)
同
File.AppendAllText(filePath, csv.ToString());
Run Code Online (Sandbox Code Playgroud)
如果你想在同一个文件中保留以前版本的csv
C#6
如果您使用的是c#6.0,则可以执行以下操作
var newLine = $"{first},{second}"
Run Code Online (Sandbox Code Playgroud)
编辑
这里是一个链接到一个问题,说明了什么Environment.NewLine呢
Pav*_*gin 83
我强烈建议你走更繁琐的路线.特别是如果您的文件很大.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
File.AppendAllText()打开一个新文件,写入内容然后关闭文件.打开文件是一项耗费大量资源的操作,而不是将数据写入开放流.打开\关闭循环内的文件将导致性能下降.
Johan建议的方法通过将所有输出存储在内存中然后将其写入一次来解决该问题.但是(在大文件的情况下)你的程序将消耗大量的RAM甚至崩溃OutOfMemoryException
我的解决方案的另一个优点是您可以通过保存输入数据中的当前位置来实现暂停\恢复.
UPD.在正确的地方使用
Jep*_*sen 27
手动编写csv文件可能很困难,因为您的数据可能包含逗号和换行符.我建议您使用现有的库.
这个问题提到了一些选择.
小智 16
我使用两个解析解决方案,因为它很容易维护
// Prepare the values
var allLines = (from trade in proposedTrades
select new object[]
{
trade.TradeType.ToString(),
trade.AccountReference,
trade.SecurityCodeType.ToString(),
trade.SecurityCode,
trade.ClientReference,
trade.TradeCurrency,
trade.AmountDenomination.ToString(),
trade.Amount,
trade.Units,
trade.Percentage,
trade.SettlementCurrency,
trade.FOP,
trade.ClientSettlementAccount,
string.Format("\"{0}\"", trade.Notes),
}).ToList();
// Build the file content
var csv = new StringBuilder();
allLines.ForEach(line =>
{
csv.AppendLine(string.Join(",", line));
});
File.WriteAllText(filePath, csv.ToString());
Run Code Online (Sandbox Code Playgroud)
只需使用AppendAllText:
File.AppendAllText(filePath, csv);
Run Code Online (Sandbox Code Playgroud)
AppendAllText的唯一缺点是当文件不存在时会抛出错误,因此必须检查
对不起,在阅读文档前的金发时刻.无论如何,如果文件存在,WriteAllText方法将覆盖先前在文件中写入的任何内容.
请注意,您当前的代码没有使用正确的新行,例如在记事本中,您将全部视为一条长行.将代码更改为具有适当的新行:
string csv = string.Format("{0},{1}{2}", first, image, Environment.NewLine);
Run Code Online (Sandbox Code Playgroud)
而不是每次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);
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
代替重新发明轮子,可以使用库。CsvHelper非常适合创建和读取csv文件。它的读取和写入操作基于流,因此也支持具有大量数据的操作。
您可以像下面这样编写csv。
using(var textWriter = new StreamWriter(@"C:\mypath\myfile.csv"))
{
var writer = new CsvWriter(textWriter);
writer.Configuration.Delimiter = ",";
foreach (var item in list)
{
writer.WriteField( "a" );
writer.WriteField( 2 );
writer.WriteField( true );
writer.NextRecord();
}
}
Run Code Online (Sandbox Code Playgroud)
当库使用反射时,它将采用任何类型并直接解析。
public class CsvRow
{
public string Column1 { get; set; }
public bool Column2 { get; set; }
public CsvRow(string column1, bool column2)
{
Column1 = column1;
Column2 = column2;
}
}
IEnumerable<CsvRow> rows = new [] {
new CsvRow("value1", true),
new CsvRow("value2", false)
};
using(var textWriter = new StreamWriter(@"C:\mypath\myfile.csv")
{
var writer = new CsvWriter(textWriter);
writer.Configuration.Delimiter = ",";
writer.WriteRecords(rows);
}
Run Code Online (Sandbox Code Playgroud)
值1,真
值2,假
如果您想了解有关库配置和可能性的更多信息,可以在这里阅读。