按行数限制CSV文件大小并自动创建新文件的C#实现
解决多字典写入CSV时的自动拆分文件问题
要实现按行数拆分输出文件,核心是跟踪已写入的行数,当达到阈值时切换到新文件。可以通过以下方式重构你的代码:
关键思路
- 维护行计数器,每写入一行就递增计数
- 维护文件索引,用于区分拆分后的多个文件
- 封装创建新StreamWriter的逻辑,方便切换文件时调用
- 每次写入后检查行数,达到上限则关闭当前文件,创建新文件并重置计数器
重构后的代码示例
const int MAX_ROWS_PER_FILE = 10000; int currentRowCount = 0; int fileIndex = 1; StreamWriter currentWriter = null; // 封装创建新写入器的方法,自动关闭旧写入器并生成带序号的新文件名 StreamWriter CreateNewWriter() { currentWriter?.Close(); string timestamp = DateTime.Now.ToString("MM.dd.yy_hh.mm.ss.tt"); string fileName = $"OutputFile-{timestamp}-{fileIndex}.csv"; fileIndex++; return new StreamWriter(Path.Combine(OutputPath, fileName)); } // 初始化第一个写入器 currentWriter = CreateNewWriter(); try { // 处理_Code1与_List1的写入逻辑 foreach (var program in _Code1) { string Id = program.ToString(); foreach (var entry in _List1) { if (!string.IsNullOrEmpty(entry.Value.ToString().Trim())) { string LineValue = entry.Value.ToString(); string[] SplitedLine = LineValue.Split(','); string query = "\"Insert into table(Id,UserID) values('" + Id + "','" + SplitedLine[1] + "')\""; currentWriter.WriteLine(query); currentRowCount++; // 检查是否需要切换文件 if (currentRowCount >= MAX_ROWS_PER_FILE) { currentWriter = CreateNewWriter(); currentRowCount = 0; } } } } // 处理_Code2与_List2的写入逻辑 foreach (var program in _Code2) { string Id = program.ToString(); foreach (var entry in _List2) { if (!string.IsNullOrEmpty(entry.Value.ToString().Trim())) { string LineValue = entry.Value.ToString(); string[] SplitedLine = LineValue.Split(','); string query = "\"Insert into table(Id,UserID) values('" + Id + "','" + SplitedLine[2] + "')\""; currentWriter.WriteLine(query); currentRowCount++; if (currentRowCount >= MAX_ROWS_PER_FILE) { currentWriter = CreateNewWriter(); currentRowCount = 0; } } } } // 处理_Code1与_List3的写入逻辑 foreach (var program in _Code1) { string Id = program.ToString(); foreach (var entry in _List3) { if (!string.IsNullOrEmpty(entry.Value.ToString().Trim())) { string LineValue = entry.Value.ToString(); string[] SplitedLine = LineValue.Split(','); string query = "Delete From table Where ID='" + Id + "' And UserID='" + SplitedLine[1] + "'"; currentWriter.WriteLine(query); currentRowCount++; if (currentRowCount >= MAX_ROWS_PER_FILE) { currentWriter = CreateNewWriter(); currentRowCount = 0; } } } } } finally { // 确保最后一个写入器被关闭,避免资源泄漏 currentWriter?.Close(); }
要点说明
- 计数器与文件切换:
currentRowCount记录当前文件已写入行数,达到MAX_ROWS_PER_FILE时调用CreateNewWriter创建新文件,同时重置计数器。 - 资源管理:通过
finally块保证最后一个StreamWriter被关闭;CreateNewWriter方法中也会关闭之前的写入器,避免资源占用。 - 文件名区分:通过
fileIndex给每个拆分后的文件添加序号(如OutputFile-05.20.24-10.30.00-AM-1.csv),避免文件名冲突。
额外提示
原代码中直接拼接SQL语句存在SQL注入风险,如果这些查询后续会被执行,建议改用参数化查询来规避安全问题。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

