我们如何在C#上使用FileMode.Append

本文关键字:FileMode Append 我们 | 更新日期: 2023-09-27 18:12:12

我一直在尝试为我的代码想出一种打开文件或创建文件的方法(如果我给定的文件名不存在(。然后,它将运行一个程序,最终创建一个数组,我希望将该数组的内容转换为字符串,并附加到我正在创建和打开的文件中。除了"附加"部分,我把所有的东西都做好了。它最后说"对象引用没有设置为对象的实例。"你能告诉我这一点吗?我们将不胜感激。

        try
        {
            FileStream fs = new FileStream("inventory.ini", FileMode.OpenOrCreate, FileAccess.Read);
            StreamReader reader = new StreamReader(fs);
            while (!reader.EndOfStream)
            {
                string line = reader.ReadLine();
                string[] data = line.Split('|');
                int code = int.Parse(data[0]);
                string name = data[1];
                double price = double.Parse(data[2]);
                Item item = new Item(code, name, price);
                app.array[inventoryCount++] = item;    
            }
            reader.Close();
            fs.Close();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        app.Run();
        try
        {
            FileStream fs = new FileStream("inventory.ini", FileMode.Append, FileAccess.Write);
            StreamWriter writer = new StreamWriter(fs);
            foreach (Item item in app.array)
            {
                writer.WriteLine(item.Code + "|" + item.Name + "|" + item.Price);
            }
            writer.Close();
            fs.Close();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        Console.ReadLine();
    }

我们如何在C#上使用FileMode.Append

您可以使用StreamWriter的另一个构造函数,它允许追加,然后这样写:

StreamWriter writer = new StreamWriter("inventory.ini", true);

我从未在我的应用程序中使用过FileStream,但StreamWriter非常可靠。您也可以切换到Using语句,然后就不需要Close()了。

此外,我建议切换到列表,这样app.array(btw需要一个更好的名称(中总会有你需要的确切数量的项目。所以这个:

app.array[inventoryCount++] = item;

会变成这样:

app.list.Add(item);

除了缓解内存管理方面的头痛,您不再需要inventoryCount变量,因为您可以从list.Count中获得该值;

这里的一般方法是在相同的功能量下,尽量减少需要编写的代码量。那么错误就没有藏身之地了。

    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }

你用这样的异常处理方式给自己挖了一个很深的坑。捕获异常的一条硬性规则是,在处理程序时恢复程序的状态。特别是,您忘记关闭文件。稍后,当您尝试再次打开文件进行写入时,就会出现错误。不幸的是,在谈到另一个已经打开文件的进程时,异常消息具有误导性。事实并非如此,您的进程仍然打开了文件。

针对这次失败有很多对策。您应该使用using语句来确保即使出现异常也会关闭文件。您需要修复EndOfStream测试,它在文本文件上不准确,使用while(true(循环,并在ReadLine((返回null时中断。这解决了最初的问题。

但真正的解决办法是不要隐瞒一个不方便的真相。当配置文件被破坏时,允许程序继续运行只会在它没有达到你希望的效果时带来更多麻烦。你无法判断,因为你写在控制台上的消息已经从屏幕上滚动掉了非常难以诊断。

从该代码中删除try/catch。现在你要解决真正的问题了。

请注意,您也可以仅使用File.AppendText()以追加模式打开StreamWriter

您还应该使用using而不是.Close()来关闭流,这样即使发生异常,它也能工作。

所以你的代码看起来更像这样:

try
{
    using (var writer = File.AppendText("inventory.ini"))
    {
        foreach (Item item in app.array)
        {
            if (item != null)
                writer.WriteLine(item.Code + "|" + item.Name + "|" + item.Price);
        }
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

为什么不使用using语句

    using (FileStream fs = new FileStream("inventory.ini", FileMode.OpenOrCreate, FileAccess.Read))
    using (StreamReader reader = new StreamReader(fs))
    {
       // do stuff
    }