You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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);
        }
    }
}

集成到你的删除流程:

  1. 找到匹配ID时,记录当前的count值(即要删除的行号)。
  2. 关闭所有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:05:13