如何用StreamReader/StreamWriter移动文件行填补删除后的空缺?
问题
我正在制作一个程序,将ID、Name、Quantity和Price四组值分别存储在四个独立文件中。目前已实现单次删除一行的功能,但删除后无法填补代码留下的空缺,尝试用for循环遍历文件并将所有内容上移一行时出现越界问题。
以下是我的代码:
static void Removestock() { StreamReader IDread = new StreamReader("IDTEXT.txt"); StreamReader NAMEread = new StreamReader("NAMETEXT.txt"); StreamReader QUANTITYread = new StreamReader("QUANTITYTEXT.txt"); StreamReader PRICEread = new StreamReader("PRICETEXT.txt"); int IDlines = System.IO.File.ReadAllLines("IDTEXT.txt").Length; int NAMElines = System.IO.File.ReadAllLines("NAMETEXT.txt").Length; int QUANTITYlines = System.IO.File.ReadAllLines("QUANTITYTEXT.txt").Length; int PRICElines = System.IO.File.ReadAllLines("PRICETEXT.txt").Length; bool finished = false; bool del = false; string ID = ""; bool found = false; bool confirm = false; string t1 = ""; string t2 = ""; string t3 = ""; string t4 = ""; int count = 0; while (finished == false) { try { Console.WriteLine("Do you want to Delete a stock or return to the menu (true/false)"); del = Boolean.Parse(Console.ReadLine()); if (del == true) { Console.WriteLine(""); Console.WriteLine("Input the Stock's ID you wish to delete"); ID = Console.ReadLine(); while (found == false) { t1 = IDread.ReadLine(); t2 = NAMEread.ReadLine(); t3 = QUANTITYread.ReadLine(); t4= PRICEread.ReadLine(); if (t1 == ID) { Console.WriteLine("Found a match!"); Console.WriteLine(); Console.WriteLine(t1 + " " + t2 + " " + t3 + " " + t4); Console.WriteLine(); confirm = Boolean.Parse(Console.ReadLine()); if (del == true) { Console.WriteLine("Deleting..."); List<string> ID2 = new List<string>(); List<string> NAME = new List<string>(); List<int> QUANTITY = new List<int>(); List<double> PRICE = new List<double>(); int temp = count; while (temp != IDlines-1) { ID2.Add(IDread.ReadLine()); NAME.Add(NAMEread.ReadLine()); QUANTITY.Add(int.Parse(QUANTITYread.ReadLine())); PRICE.Add(double.Parse(PRICEread.ReadLine())); temp = temp + 1; } IDread.Close(); NAMEread.Close(); QUANTITYread.Close(); PRICEread.Close(); StreamWriter IDW = new StreamWriter("IDTEXT.txt"); StreamWriter NMW = new StreamWriter("NAMETEXT.txt"); StreamWriter QUW = new StreamWriter("QUANTITYTEXT.txt"); StreamWriter PRW = new StreamWriter("PRICETEXT.txt"); for (int i = count; i < IDlines; i++) { IDW.Write(ID2[i]); NMW.Write(NAME[i]); QUW.Write(QUANTITY[i]); PRW.Write(PRICE[i]); } } } else { count = count + 1; } } } else { Console.WriteLine("Exiting System.Delete now..."); finished = true; } } catch { } } IDread.Close(); NAMEread.Close(); QUANTITYread.Close(); PRICEread.Close(); }
补充说明:我了解过其他实现方式,但希望尽量不使用System.IO.File相关方法,专注于StreamReader和StreamWriter实现文本行上移填补文件空缺。同时也希望得到代码其他潜在问题的建议。另外,我认为CSV较为复杂,将留到后续项目再研究,暂不考虑;也可忽略使用四个独立文件的设计,只需针对单个文件实现逻辑后复用四次即可。
解决方案与改进建议
一、解决越界与空缺填补问题
核心问题是删除匹配行后未保留前面的行,且写入索引逻辑错误。以下是单文件的删除实现逻辑,可直接复用四次处理四个文件:
static void DeleteLineFromFile(string filePath, int lineToDelete) { // 用StreamReader读取所有行并存储 List<string> lines = new List<string>(); using (StreamReader reader = new StreamReader(filePath)) { string line; while ((line = reader.ReadLine()) != null) { lines.Add(line); } } // 删除目标行 if (lineToDelete >= 0 && lineToDelete < lines.Count) { lines.RemoveAt(lineToDelete); } // 用StreamWriter将处理后的内容写回文件 using (StreamWriter writer = new StreamWriter(filePath)) { foreach (string line in lines) { writer.WriteLine(line); } } }
集成到你的删除流程:
- 找到匹配ID时,记录当前的
count值(即要删除的行号)。 - 关闭所有
StreamReader后,调用四次上述方法,分别传入四个文件路径和count值,自动完成行上移,解决空缺和越界问题。
二、代码其他潜在问题的改进建议
- 用
using管理流资源:手动调用Close()可能因异常导致资源泄漏,using语句会自动释放资源,示例:using (StreamReader IDread = new StreamReader("IDTEXT.txt")) { // 读取逻辑 } - 移除空catch块:空catch会隐藏所有错误(如文件不存在、格式转换失败),至少输出错误信息方便调试:
catch (Exception ex) { Console.WriteLine($"发生错误: {ex.Message}"); } - 修正删除条件逻辑:当前用
if (del == true)判断是否执行删除,应改为判断confirm是否为true,避免用户未确认就执行删除。 - 校验文件行数一致性:四个文件的行号必须严格对应,建议程序启动时校验四文件行数是否一致,防止数据错乱。
- 优化行数获取逻辑:多次调用
File.ReadAllLines()获取行数效率低,可在读取所有行时直接获取列表长度。 - 处理ID不存在的情况:若输入ID不存在,
found永远为false,会循环读取到文件末尾引发异常。需在读取行时判断是否为null,若为null则提示ID不存在并退出循环。
内容的提问来源于stack exchange,提问作者GayCriminal
相关产品推荐
相关产品推荐

