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

时间:2013-05-04 17:03:43

标签: c#

我一直在尝试为我的代码打开一个文件或创建一个文件(如果我的文件名不存在)。之后,它将运行一个程序,最终将创建一个数组,我希望将该数组的内容转换为字符串并附加到我正在创建和打开的文件中。除了“附加”部分,我已经把一切都搞定了。它最终说“对象引用未设置为对象的实例”。你能不能请教我这个?非常感谢帮助。

        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();
    }

4 个答案:

答案 0 :(得分:2)

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

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

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

此外,我建议切换到lists,然后您将始终拥有app.array内所需的确切数量的项目(btw需要更好的名称)。所以这个:

app.array[inventoryCount++] = item;

将改为这样:

app.list.Add(item);

除了记忆管理头痛缓解外,您不再需要inventoryCount变量,因为您可以从list.Count获得此值;

这里的一般方法是尽量减少您需要编写的代码量,以获得相同数量的功能。然后你没有地方可以潜伏这个错误。

答案 1 :(得分:2)

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

你正在挖掘自己一个非常深的洞,这样的异常处理。捕获异常的一个硬性规则是在处理程序时恢复程序的状态。你没有。特别是,您忘记关闭文件。之后,当您尝试再次打开文件进行写入时,这就出错了。遗憾的是,异常消息具有误导性,正在讨论已经打开文件的另一个进程。不是这样,你的进程仍然打开了文件。

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

但真正的解决方法是不要隐瞒一个不方便的事实。允许您的程序在配置文件被破坏时继续运行只会在它没有按照您希望的方式执行时遇到更多麻烦。而你无法分辨,因为你写入控制台的消息已经滚动到屏幕上。 非常难以诊断。

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

答案 2 :(得分:0)

请注意,您也可以使用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);
}

答案 3 :(得分:0)

为什么不使用 using statement

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