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

また、リストに切り替えることをお勧めします。そうすれば、必要なアイテムの正確な量が常に内部に含まれます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 に答える