簡體   English   中英

用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;

但這沒有用。 嘗試了一些我在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))

trueleaveOpen

        // 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM