使用 CsvHelper 读取 CSV 文件后如何写入?
How to write a CSV file after reading it with CsvHelper?
在使用 CsvHelper nuget 包将其映射到列表后,我需要编写一个 HttpPostedFileBase
csv(并保存)。但是,在使用 CsvHelper 映射之后,ContentLength
为 0,我最终保存了一个空的 .csv 文件。
CsvHelper 本身声明在使用 GetRecords<T>()
方法时不应使用 Read 方法。
// Summary:
// Gets all the records in the CSV file and converts each to System.Type T. The
// Read method should not be used when using this.
//
// Type parameters:
// T:
// The System.Type of the record.
//
// Returns:
// An System.Collections.Generic.IEnumerable`1 of records.
public virtual IEnumerable<T> GetRecords<T>();
我试着把它放到一个复制变量中:
HttpPostedFileBase csvCopy = csvFile;
但这没有用。尝试了我在 Whosebug 上找到的其他一些解决方案,但也没有用。我 "solved" 通过将同一个文件作为参数两次发送到控制器来解决这个问题。然后我将第一个与 CsvHelper 一起使用,我读取并保存另一个。
public async Task<ActionResult> ImportCSV(HttpPostedFileBase csvFile, HttpPostedFileBase csvFileCopy)
但是,我认为这是一个糟糕的解决方案。我想使用单个文件,映射它,重新读取它并保存它。
将其映射到列表中:
using(var reader = new StreamReader(csvFile.InputStream)) {
using(var csvReader = new CsvReader(reader)) {
csvReader.Configuration.RegisterClassMap(new CSVModelMap(mapDictionary));
csvReader.Configuration.BadDataFound = null;
csvReader.Configuration.HeaderValidated = null;
csvReader.Configuration.MissingFieldFound = null;
importData = csvReader.GetRecords<CSVModel>().ToList();
}
}
正在保存:
var fileName = serverPath + "\" + hashedFileName;
CheckIfDirectoryExists(serverPath);
var reader = new StreamReader(csvFile.InputStream);
var csvContent = await reader.ReadToEndAsync();
File.WriteAllText(fileName, csvContent);
我不确定 GetRecords 是如何工作的,但它有可能将光标留在指向末尾的流上。
意思是你的保存序列在最后开始读取 InputStream,这导致没有数据可读。
所以你可以试试
csvFile.InputStream.Seek(0, SeekOrigin.Begin)
编辑:
对于复制流的尝试,您只复制了对对象的引用,而不是对象本身。
要复制流数据,您需要使用 CopyTo(stream)
方法,该方法会将光标留在流的末尾,因此这里肯定需要查找。
问题是 CsvHelper:
using(var csvReader = new CsvReader(reader))
在 using 语句结束时,CsvReader
关闭 reader。然后当我尝试
csvFile.InputStream.Seek(0, SeekOrigin.Begin);
或
reader.BaseStream.Position = 0;
它抛出一个 NullReferenceException
。我通过简单地覆盖 CsvReader
:
解决了这个问题
using (var csvReader = new CsvReader(reader, true))
true
是 leaveOpen
:
// Summary:
// Creates a new CSV reader using the given System.IO.TextReader.
//
// Parameters:
// reader:
// The reader.
//
// leaveOpen:
// true to leave the reader open after the CsvReader object is disposed, otherwise
// false.
public CsvReader(TextReader reader, bool leaveOpen);
然后我使用reader.BaseStream.Position = 0;
将位置设置回0,然后在保存文件后,处理reader。
在使用 CsvHelper nuget 包将其映射到列表后,我需要编写一个 HttpPostedFileBase
csv(并保存)。但是,在使用 CsvHelper 映射之后,ContentLength
为 0,我最终保存了一个空的 .csv 文件。
CsvHelper 本身声明在使用 GetRecords<T>()
方法时不应使用 Read 方法。
// Summary:
// Gets all the records in the CSV file and converts each to System.Type T. The
// Read method should not be used when using this.
//
// Type parameters:
// T:
// The System.Type of the record.
//
// Returns:
// An System.Collections.Generic.IEnumerable`1 of records.
public virtual IEnumerable<T> GetRecords<T>();
我试着把它放到一个复制变量中:
HttpPostedFileBase csvCopy = csvFile;
但这没有用。尝试了我在 Whosebug 上找到的其他一些解决方案,但也没有用。我 "solved" 通过将同一个文件作为参数两次发送到控制器来解决这个问题。然后我将第一个与 CsvHelper 一起使用,我读取并保存另一个。
public async Task<ActionResult> ImportCSV(HttpPostedFileBase csvFile, HttpPostedFileBase csvFileCopy)
但是,我认为这是一个糟糕的解决方案。我想使用单个文件,映射它,重新读取它并保存它。
将其映射到列表中:
using(var reader = new StreamReader(csvFile.InputStream)) {
using(var csvReader = new CsvReader(reader)) {
csvReader.Configuration.RegisterClassMap(new CSVModelMap(mapDictionary));
csvReader.Configuration.BadDataFound = null;
csvReader.Configuration.HeaderValidated = null;
csvReader.Configuration.MissingFieldFound = null;
importData = csvReader.GetRecords<CSVModel>().ToList();
}
}
正在保存:
var fileName = serverPath + "\" + hashedFileName;
CheckIfDirectoryExists(serverPath);
var reader = new StreamReader(csvFile.InputStream);
var csvContent = await reader.ReadToEndAsync();
File.WriteAllText(fileName, csvContent);
我不确定 GetRecords 是如何工作的,但它有可能将光标留在指向末尾的流上。
意思是你的保存序列在最后开始读取 InputStream,这导致没有数据可读。
所以你可以试试
csvFile.InputStream.Seek(0, SeekOrigin.Begin)
编辑:
对于复制流的尝试,您只复制了对对象的引用,而不是对象本身。
要复制流数据,您需要使用 CopyTo(stream)
方法,该方法会将光标留在流的末尾,因此这里肯定需要查找。
问题是 CsvHelper:
using(var csvReader = new CsvReader(reader))
在 using 语句结束时,CsvReader
关闭 reader。然后当我尝试
csvFile.InputStream.Seek(0, SeekOrigin.Begin);
或
reader.BaseStream.Position = 0;
它抛出一个 NullReferenceException
。我通过简单地覆盖 CsvReader
:
using (var csvReader = new CsvReader(reader, true))
true
是 leaveOpen
:
// Summary:
// Creates a new CSV reader using the given System.IO.TextReader.
//
// Parameters:
// reader:
// The reader.
//
// leaveOpen:
// true to leave the reader open after the CsvReader object is disposed, otherwise
// false.
public CsvReader(TextReader reader, bool leaveOpen);
然后我使用reader.BaseStream.Position = 0;
将位置设置回0,然后在保存文件后,处理reader。