0

我一直试图想出一种方法让我的代码打开文件或创建一个文件(如果我给定的文件名不存在)。之后,它将运行一个程序,该程序最终将创建一个数组,我希望将该数组的内容转换为字符串并附加到我正在创建和打开的文件中。除了“追加”部分,我一切都做对了。它最后说“对象引用未设置为对象的实例”。你能告诉我这个吗?帮助将不胜感激。

        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

4 回答 4

2

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

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

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

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

app.array[inventoryCount++] = item;

会变成这样:

app.list.Add(item);

除了缓解内存管理头痛之外,您不再需要inventoryCount变量,因为您可以从list.Count;

这里的一般方法是最小化您需要编写的代码量,以实现相同数量的功能。那么你就没有地方让错误潜伏了。

于 2013-05-04T17:07:26.220 回答
2
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }

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

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

但真正的解决办法是不要隐藏一个不方便的事实。当配置文件损坏时允许程序继续运行只会带来更多麻烦,因为它没有按照您希望的方式执行。而且您无法分辨,因为您写入控制台的消息已从屏幕上滚动出来。 很难诊断。

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

于 2013-05-05T13:05:24.457 回答
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);
}
于 2013-05-04T18:24:16.140 回答
0

为什么不使用using 语句

    using (FileStream fs = new FileStream("inventory.ini", FileMode.OpenOrCreate, FileAccess.Read))
    using (StreamReader reader = new StreamReader(fs))
    {
       // do stuff
    }
于 2013-05-05T10:41:32.357 回答