我开始使用CSV Helper - 一个非常适合日常工作的小帮手 - 很棒的东西!
我现在正在努力的一个项目是班级地图 - 我有一个小班级
public class SimpleClass
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Percentage { get; set; }
public bool IsValid { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并且为了导出到CSV,我想用,用; 替换IsValid值; 为此,我创建了一个类映射:trueyesFalseno
public class SimpleClassMap : CsvClassMap<SimpleClass>
{
public override void CreateMap()
{
Map(x => x.ID).Index(0);
Map(x => x.Name).Index(1);
Map(x => x.Percentage).Index(2);
Map(x => x.IsValid).Index(3)
.TypeConverterOption(true, "yes")
.TypeConverterOption(false, "no"); …Run Code Online (Sandbox Code Playgroud) 如果我有一些LF转换(使用N ++)CSV文件,每次我使用JoshClose将数据写入它们时CsvHelper,行结尾将返回CRLF.
由于我ROWTERMINATORS在SQL Server 中遇到CLRF问题,所以我要保持我的行结尾像文件的初始状态.
无法在文化设置中找到它,我编译自己的库版本.
如何进行?
我正在使用CsvHelper.要写入.csv文件,我需要一个基于类的头.
我手动编写标题并且它可以工作,但我需要在读取时自动完成.
我能找到的所有文档都说要使用这个表达式,writer.WriteHeader<CSVDataFormat>();但这不起作用,因为它需要做更多的工作.
以下是标题应该基于的类:
public class CSVDataFormat
{
public string FirstName { get; set; }
public string LastName { get; set; }
public float Wage { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是阅读和写作的代码:
private void ReadCSV(string ogCsvFile)
{
using (var streamReaederfileDir = new StreamReader(@ogCsvFile))
{
using (var streamWriterFileDir = new StreamWriter(Path.Combine(Path.GetDirectoryName(ogCsvFile), "New" + Path.GetFileName(ogCsvFile))))
{
var reader = new CsvReader(streamReaederfileDir);
var writer = new CsvWriter(streamWriterFileDir);
writer.WriteHeader<CSVDataFormat>();
IEnumerable records = reader.GetRecords<CSVDataFormat>().ToList();
foreach (CSVDataFormat record in records)
{
record.Wage = …Run Code Online (Sandbox Code Playgroud) 我正在使用CsvHelper编写一些CSV文件,并想将日期和时间的格式更改为特定的格式。遵循/sf/answers/2227233501/的建议, 我可以为我的每个类成功创建映射。
但是,它有一个明显的缺点,即我现在需要为要导出的所有类创建自定义映射。因为我一直希望导出的所有字段都成为维护的噩梦,因为每次都必须修改地图。
那么,有什么简单的方法可以告诉CsvHelper 使用特定格式写入所有日期和时间?
我正在尝试读取标题位于第 3 行的 CSV 文件:
some crap line
some empty line
COL1,COL2,COl3,...
val1,val2,val3
val1,val2,val3
Run Code Online (Sandbox Code Playgroud)
如何告诉CSVHelper标题不在第一行?
我试图跳过 2 行,Read()但随后的调用ReadHeader()引发了一个异常,表明标题已被读取。
using (var csv = new CsvReader(new StreamReader(stream), csvConfiguration)) {
csv.Read();
csv.Read();
csv.ReadHeader();
.....
Run Code Online (Sandbox Code Playgroud)
如果我设置csvConfiguration.HasHeaderRecord为false ReadHeader()再次失败。
假设我有一个很大的csv文件,我想读取,修改和写回。也许我想将字段分隔符从逗号更改为制表符。也许我想将引号从'更改为“。或者我想在第一列的每个值上添加一个加号。由于文件很大,所以我不想一次全部加载到内存中,我想逐条阅读。
所以我写了这样的代码:
var inPath = @"infile.txt";
var outPath = @"outfile.txt";
CsvConfiguration readCf = GetReadConfiguration();
CsvConfiguration writeCf = GetWriteConfiguration();
using (var streamin = new FileStream(inPath, FileMode.Open))
using (var streamReader = new StreamReader(streamin))
{
using (var csvReader = new CsvReader(streamReader, readCf))
using (var csvWriter = new CsvWriter(new StreamWriter(outPath), writeCf))
{
while (csvReader.Read())
{
var currentRecord = csvReader.GetRecord<dynamic>();
UpdateRecord(currentRecord);
csvWriter.WriteRecord(currentRecord);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将在运行时失败,并显示以下错误:
继承IEnumerable的类型无法自动映射。您是否意外地调用了作用于单个记录的GetRecord或WriteRecord而不是调用了作用于记录列表的GetRecords或WriteRecords?
请注意,中没有有趣的事情发生UpdateRecord,实际上上面的这一行可以完全注释掉。
发生的情况是GetRecord返回an ExpandoObject,然后WriteRecord对此对象造成阻塞。
使这项工作最好的方法是什么?
更新
显而易见,我很清楚:我完全收到此错误是因为CSVHelper不支持ExpandoObjects进行WriteRecord …
我使用CsvHelper 4.0.3.
我有一个像这样定义的嵌套类:
private class CsvLine {
public string Solution;
public string Project;
public string DependsOnProject;
public string Weight;
public string DependsOnPackage;
public string PackageVersion;
}
Run Code Online (Sandbox Code Playgroud)
我想要解析的.csv文件CsvHelper具有以下字段名称:
Solution,Project,DependsOnProject,Weight,DependsOnPackage,PackageVersion
这是我的代码:
TextReader readFile = new StreamReader(dependenciesCsvFilePath);
var csvReader = new CsvReader(readFile);
IEnumerable<CsvLine> records = csvReader.GetRecords<CsvLine>();
Run Code Online (Sandbox Code Playgroud)
根据这里的文档,上面的代码应该工作.
但是,当我检查时records,我看到了这个消息No members are mapped for type 'ParentClass+CsvLine'.
我改变的可访问性CsvLine,从private到public,但是这并没有区别.
我做错了什么?
编辑:我已经尝试取消嵌套CsvLine类并将其公开,但这也没有帮助.
编辑:我按照Nkosi的建议做了改变; 然而,现在它说这 …
[Serializable]
public abstract class AbstractModel : ObservableObject
{
// nothing.
}
public class RealModel : AbstractModel
{
public string PropertyA {get; set;}
public string PropertyB {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这ObservableObject是来自Mvvm-light.
对于上面的模型,我使用CsvHelper如下.
AbstractModel instance = new RealModel()
{
PropertyA = "foo",
PropertyA = "bar"
};
using (TextWriter file = new StreamWriter("path"))
using (var csv = new CsvWriter(file))
{
csv.WriteRecord(instance);
}
Run Code Online (Sandbox Code Playgroud)
它抛出错误如下;
没有为"AbstractModel"类型映射属性
当我设置时,它工作正常RealModel instance = new RealModel();.但是,我有各种派生类,并希望将它们保存在一个Save方法中.
我能怎么做?
我有一个服务,它接受一个包含需要批量插入数据库的 CSV 数据的输入流,并且我的应用程序尽可能使用 async/await。
过程是:使用CsvHelper的CsvParser解析流,将每一行添加到DataTable中,使用SqlBulkCopy将DataTable拷贝到数据库中。
数据可以是任何大小,所以我想避免一次将整个内容读入内存 - 显然我最终将在 DataTable 中拥有所有数据,因此在内存中基本上会有 2 个副本。
我想尽可能异步地完成所有这些,但 CsvHelper 没有任何异步方法,所以我想出了以下解决方法:
using (var inputStreamReader = new StreamReader(inputStream))
{
while (!inputStreamReader.EndOfStream)
{
// Read line from the input stream
string line = await inputStreamReader.ReadLineAsync();
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var memoryStreamReader = new StreamReader(memoryStream))
using (var csvParser = new CsvParser(memoryStreamReader))
{
await streamWriter.WriteLineAsync(line);
await streamWriter.FlushAsync();
memoryStream.Position = 0;
// Loop through all the rows (should only be one as …Run Code Online (Sandbox Code Playgroud) 我们有一个面向目标的项目,netstandard2.0该项目使用 NuGet 包CsvHelper,该包也可作为netstandard2.0.
该项目包含CsvConfiguration构建为的类:
public class CsvConfiguration
{
public virtual string Delimiter { get; init; }
}
Run Code Online (Sandbox Code Playgroud)
我们过去使用这个库没有任何问题。将 Visual Studio 从 16.8.6 更新到 16.9.0 后,生成时出现上述错误消息:
error CS8370: Feature 'init-only setters' is not available in C# 7.3. Please use language version 9.0 or greater.
Run Code Online (Sandbox Code Playgroud)
虽然我理解为什么会发生此错误,但如果我在自己的代码中使用此功能,我不知道如果第三方库使用它(声明为与我的框架版本匹配)为什么会发生这种情况。
这是库中还是 Visual Studio 中的错误?因为在 VS 16.8.6 中它编译得很好,而在 VS 16.9.0 中它失败了。
我知道,一个简单的解决方法是<LangVersion>在我们的 .csproj 文件中添加一个条目,但这是推荐的方法吗?
c# ×10
csvhelper ×10
.net ×4
csv ×3
.net-4.0 ×1
asp.net ×1
async-await ×1
asynchronous ×1
line-endings ×1
stream ×1