CSV文件读取问题:行尾多逗号原因、指定值访问及分组导出
CSV读取相关问题解答
原读取代码
void ReadFromCsv() { using (var reader = new StreamReader(@"d:\test.csv", Encoding.Default)) { List<string> listA = new List<string>(); while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(';'); listA.Add(values[0]); } Console.WriteLine(listA); } }
示例CSV行
50,2,10,201,10,9090339,24-OCT-21 09.38.38.679000 AM,123456789,24/10/2021 09:39:23,22/10/2021 09:39:37,Sm123456789-SM-20211031-VSR-000123.pdf,,,,,26/01/2022 13:08:58,,2,,0
问题1:该行末尾存在多个连续逗号的原因是什么?
连续逗号代表对应位置的CSV字段为空值。CSV是按固定列结构存储数据的,即使某行末尾几列没有数据,也需要用逗号占位来保持列数和表头(或其他行)一致,避免解析时出现列错位的问题。这些连续逗号就是空字段的占位符,用来维持整个文件的结构完整性。
问题2:如何访问该行中的第5个值(示例中为"10")?
首先要修正原代码的错误:示例CSV行用逗号分隔,但原代码用了Split(';'),这会导致分割结果完全错误,必须改成Split(',')。
其次,C#数组索引从0开始,第5个值对应的索引是4。还要加判断避免列数不足时的索引越界问题,修改后的代码如下:
void ReadFromCsv() { using (var reader = new StreamReader(@"d:\test.csv", Encoding.Default)) { while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); // 先判断列数是否足够,防止索引越界 if (values.Length >= 5) { string fifthValue = values[4]; Console.WriteLine(fifthValue); // 输出示例中的"10" } } } }
问题3:如何根据第5个值的内容,将对应行分组导出到不同的CSV文件中?
可以用字典按第5个值分组存储行,再分别写入独立的CSV文件,具体实现如下:
void GroupAndExportCsv() { // 用字典存储分组:键是第5个值,值是对应行的集合 var groupedRows = new Dictionary<string, List<string>>(); string csvPath = @"d:\test.csv"; string exportDir = @"d:\csv_groups\"; // 确保导出目录存在 Directory.CreateDirectory(exportDir); using (var reader = new StreamReader(csvPath, Encoding.Default)) { // 读取表头(如果CSV有表头,需要写入每个分组文件) string header = reader.ReadLine(); while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); if (values.Length < 5) continue; // 跳过列数不足的无效行 string groupKey = values[4]; // 如果当前分组不存在,先创建并写入表头 if (!groupedRows.ContainsKey(groupKey)) { groupedRows[groupKey] = new List<string>(); using (var writer = new StreamWriter(Path.Combine(exportDir, $"group_{groupKey}.csv"), false, Encoding.Default)) { writer.WriteLine(header); } } // 将当前行追加写入对应分组的文件 using (var writer = new StreamWriter(Path.Combine(exportDir, $"group_{groupKey}.csv"), true, Encoding.Default)) { writer.WriteLine(line); } } } }
说明:如果CSV没有表头,直接删除读取表头的相关逻辑即可;代码中用
StreamWriter的追加模式写入,避免覆盖已有的分组内容。
内容的提问来源于stack exchange,提问作者user20622377
相关产品推荐
相关产品推荐

