0

私が取り組んでいるWindowsフォームプロジェクトがあります。保存して終了するオプションを備えたメニューストリップがあります。

いずれかのアクションを初めて実行すると、ファイルが保存されます。ユーザーにダイアログ ボックスが表示され、次にファイル名とパスを選択すると、すばらしい保存が行われます。

ただし、追加の保存では、ファイルが既に存在するため、ファイルを上書きすることを想定していますが、代わりに末尾に追加しています。したがって、本質的には、同じ情報をファイルに 2 回出力しています。

保存およびクローズのイベント ハンドラーは次のとおりです。

private void saveToolStripMenuItem_Click(object sender, EventArgs e)
    {
        saveCurrentFile("save");
    }

    private void exitToolStripMenuItem_Click(object sender, EventArgs e)
    {
        saveCurrentFile("exit");
        this.Close();
    }

保存方法は次のとおりです。

private void saveCurrentFile(string sender)
    {
        // Check who called this method for the first time, if it was the save menu option, no need to ask if they want to
        // save, just show the user the prompt
        // If it was the exit menu option, ask user if they want to save
        if (sender.CompareTo("save") == 0)
        {
            if (fileName == "")
            {
                saveFileDialog1.ShowDialog();
                fileName = saveFileDialog1.FileName;
            }
        }
        else if (sender.CompareTo("exit") == 0)
        {
            // Display a messagebox to ask user if they want to save
            DialogResult dResult = new DialogResult();
            dResult = MessageBox.Show("Would you like to save?", "Save", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);

            // Check what button the user pressed
            if (dResult == DialogResult.Yes)
            {
                if (fileName == "")
                {
                    saveFileDialog1.ShowDialog();
                    fileName = saveFileDialog1.FileName;
                }
            }
        }

        // Now check if the fileName is empty
        if (fileName != "")
        {
            DateTime date = DateTime.Now;

            // Add some header information to the string builder
            sb.AppendLine("Budget Information");
            sb.Append("Date & Time File Saved: ");
            sb.AppendLine(date.ToString());
            sb.Append("\r\n");
            sb.Append("\r\n");

            // Add the income data to the string builder
            sb.AppendLine("Hourly Wage: " + hourlyUpDown.Value.ToString("C"));
            sb.AppendLine("Annual Salary: " + annualUpDown.Value.ToString("C"));
            sb.AppendLine("Tax: " + taxUpDown.Value.ToString());
            sb.AppendLine("Hours Per Week: " + hoursPerWeekUpDown.Value.ToString());
            sb.AppendLine("Weeks Per Year: " + weeksPerYearUpDown.Value.ToString());
            sb.AppendLine("Net Weekly Income: " + netWeeklyIncome.ToString("C"));
            sb.AppendLine("Net Monthly Income: " + netMonthlyIncome.ToString("C"));
            sb.AppendLine("Net Annual Income: " + netAnnualIncome.ToString("C"));

            // Add the expenses table to the string builder
            foreach (KeyValuePair<TextBox, TextBox> entry in expenses)
            {
                sb.AppendLine(entry.Key.Text + " " + entry.Value.Text);
            }

            // Add a note to the user about modifying the file by hand
            sb.Append("\r\n");
            sb.Append("\r\n");
            sb.AppendLine("This file is created in a specific format.");
            sb.AppendLine("Any modifications to it may cause errors when the program tries to open and read the file contents.");
            sb.AppendLine("Any changes made by hand must conserve the formatting");

            using (StreamWriter outfile = new StreamWriter(fileName, false))
            {
                outfile.Write(sb.ToString());
                outfile.Flush();
                outfile.Close();
            }
        }
    }

ファイルが2回書き込まれている理由がわかりません。outfile.Flush()問題を解決しようととを追加しましたoutfile.Close()が、うまくいきませんでした。

どんな助けでも素晴らしいでしょう。


編集:コードを更新して、保存に1つの方法のみを使用するようにしました。バグは、当初考えていたよりも少し複雑です。

ユーザーがファイルを保存するたびに、出力がファイルに追加されます。したがって、ユーザーが [メニュー] -> [保存] に移動してファイルを保存すると、出力がファイルに書き込まれます。後続の保存ごとに、出力が追加されます。

何が問題なのかわかりません。ストリームライターにブール値の追加パラメーターを使用し、フラッシュして閉じています。

4

1 に答える 1

0

申し訳ありませんが、私の間違いです。

ファイルが書き込まれて閉じられた後、stringbuilder の内容をクリアするのを忘れていました。

using(){}したがって、ステートメントの直後にsb.Clear()、文字列ビルダーをクリアするために使用すると、機能するようになりました。

補足として、ファイルの上書きを確実にするために、ストリーム書き込みオブジェクトが false ブール値パラメーターで作成されていることを確認しました。

于 2013-09-13T14:41:15.083 に答える