[英]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;
但這沒有用。 嘗試了一些我在stackoverflow上發現的其他解決方案,這些解決方案也不起作用。 通過將兩次相同的文件作為參數發送到控制器,我“解決了”這個問題。 然后,我將第一個與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
關閉閱讀器。 然后當我嘗試
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;
將位置設置回reader.BaseStream.Position = 0;
,然后保存文件后,處置閱讀器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.