2016-12-02 96 views
4

假設我有一個大的csv文件,我想要讀取,修改和回寫。也許我想將字段分隔符從逗號更改爲製表符。也許我想將引號字符從'改爲',或者可能是我想爲第一列中的每個值添加一個加號,由於文件很大,我不想一次加載到內存中,我想讀它通過記錄記錄更改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); 
     } 
    } 
} 

這種失敗在運行時,出現以下錯誤:

Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?

。注意,沒有什麼有趣的事發生在UpdateRecord,其實這一行上面可以完全評論ou噸。

發生什麼事是GetRecord返回ExpandoObject,然後WriteRecord扼流器在此對象上。

使這項工作的最佳方式是什麼?

更新 只是所以很清楚:我充分認識到,我得到這個錯誤是因爲CSVHelper不支持ExpandoObject S表示WriteRecord電話。我正在尋找建議,以便完成此項工作。

+0

錯誤是告訴你使用GetRecords(複數)而不是單數。我的意思是它暗示它。你嘗試過嗎? – CodingYoshi

+0

@CodingYoshi,不,我不需要。 –

+0

看看Mar L的答案[這裏](http://stackoverflow.com/questions/33294738/read-all-values-from-csv-into-a-list-using-csvhelper),看看是否有幫助你。 – CodingYoshi

回答

4

this commit中似乎增加了寫入ExpandoObject的能力。

請注意,這不是最新的Nuget版本(截至編寫時爲2.16.3),而是下一個3.x版本。如果這是您從github獲得最新測試版的選項並使用它。

如果這樣做,請注意,您必須在每個WriteRecord之後致電NextRecord。在2.16.3 CVSHelper會爲你調用它,所以這是一個突破API的變化

+0

舊版本給了我'CsvConfigurationException:繼承IEnumerable的類型不能被自動映射。您是否意外地調用了GetRecord或WriteRecord,它只作用於單個記錄,而不是調用GetRecords或WriteRecords作用於記錄列表?'和新版本(3.0)給了我'CsvTypeConverterException:轉換IEnumerable類型不支持單個字段。如果您想這樣做,請創建您自己的ITypeConverter,並通過調用AddConverter將其註冊到TypeConverterFactory中。 –