如何在C#中检测CSV文件的空单元格及新增行?
我来帮你梳理下这两个需求的可行思路,结合你现有的代码来调整:
一、检测文件是否新增行
要检测CSV文件是否新增行,核心是记录上次读取时的行数,下次读取时对比当前行数和历史记录即可。具体可以这么做:
- 选择一个存储历史行数的方式:比如把上次的行数存在本地配置文件(如
appsettings.json)、本地数据库,甚至是一个简单的文本文件里。 - 每次读取CSV文件前,先读取存储的历史行数;读取完成后,对比当前有效行数和历史行数:
- 如果当前行数 > 历史行数,说明有新增行,新增的行数就是两者的差值,你还可以直接提取新增的行(从
validLines[lastRowCount + 1..]开始的部分,+1是跳过表头)。 - 如果行数不变或减少,说明没有新增(或者有行被删除/修改)。
- 如果当前行数 > 历史行数,说明有新增行,新增的行数就是两者的差值,你还可以直接提取新增的行(从
注意:如果文件可能被完全替换(比如旧文件被删除,新文件同名),建议同时记录文件的最后修改时间或文件哈希值,先验证文件是否是同一个,再对比行数,避免误判。
二、检测文件中是否存在空单元格
要检测空单元格,只需要遍历所有行的所有元素,检查是否存在空白(包括空字符串、全空格的字符串)即可:
- 遍历你生成的
csv集合中的每一行,再遍历行内的每个元素; - 对每个元素执行
string.IsNullOrWhiteSpace(cell)判断,如果有任意一个元素满足这个条件,就标记该文件存在空单元格; - 可以选择是否跳过表头行:如果你的第一行是表头,不需要检测表头的空单元格,就从第二行开始遍历。
结合现有代码的修改示例
把这两个功能整合到你的代码里,大概是这样:
// 假设你已经从存储中读取了对应文件的上次行数,这里用变量模拟 int lastRowCount = LoadLastRowCount(item); // 自定义方法:从存储读取该文件的上次有效行数 var contents = File.ReadAllText(item).Split('\n'); // 过滤掉空行(比如文件末尾的换行符产生的无效行),避免行数统计错误 var validLines = contents.Where(line => !string.IsNullOrWhiteSpace(line)).ToList(); var csv = validLines.Select(line => line.Split(';')).ToArray(); // 检测新增行(validLines.Count-1是去掉表头后的有效数据行数) bool hasNewRows = validLines.Count - 1 > lastRowCount; int newRowCount = hasNewRows ? (validLines.Count - 1 - lastRowCount) : 0; // 检测空单元格(这里跳过表头,从第二行开始遍历数据行) bool hasEmptyCells = csv.Skip(1).Any(row => row.Any(cell => string.IsNullOrWhiteSpace(cell))); // 更新存储的行数,供下次读取时对比 SaveLastRowCount(item, validLines.Count - 1); // 自定义方法:把当前行数保存到存储 list.Add(new CSVFile { Colums = csv.FirstOrDefault()?.Length ?? 0, // 空文件时避免空引用异常 Rows = validLines.Count - 1, Date = DateTime.Now, Report = item.Split("\\").LastOrDefault(), HasNewRows = hasNewRows, // 新增属性:标记是否有新增行 NewRowCount = newRowCount, // 新增属性:记录新增行数 HasEmptyCells = hasEmptyCells // 新增属性:标记是否存在空单元格 });
几点补充说明:
- 原代码用
Split('\n')可能会得到空行,所以加了Where(line => !string.IsNullOrWhiteSpace(line))过滤无效行,保证行数统计准确。 - 把
csv.FirstOrDefault().Count()改成csv.FirstOrDefault()?.Length ?? 0,避免文件为空时出现空引用异常。 LoadLastRowCount和SaveLastRowCount需要你自己实现,比如用File.WriteAllText把每个文件的行数存在本地JSON文件,或者用数据库存储。
内容的提问来源于stack exchange,提问作者Sultan Ahmed
相关产品推荐
相关产品推荐

