Search code examples
c#winformsfilefilestreamstreamwriter

Won't write to a text file


I have created this to a form. If receives all the info and seems to work, but when I check the text file nothing is written there, and it only lets me run the form twice before erroring out. Anyone see the problem?

const string FileName = "Friends.txt";
Friend friend = new Friend();
FileStream file = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
FileStream file2 = new FileStream(FileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); 

public Form1()
{
    InitializeComponent();
}

private void enter_Click(object sender, EventArgs e)
{
    StreamWriter write = new StreamWriter(file2);

    try
    {
        friend.FirstName = firstName.Text;
        friend.LastName = lastName.Text;
        friend.PhoneNumber = phoneNumber.Text;
        friend.Month = Convert.ToInt32(birthMonth.Text);
        friend.Day = Convert.ToInt32(birthday.Text);
        write.WriteLine(friend.ToString());
        MessageBox.Show("Wrote " + friend.ToString() + " to file.");
    }
    catch(Exception error)
    {
        MessageBox.Show(error.Message + " Please reenter the information.");
    }
    firstName.Clear();
    lastName.Clear();
    phoneNumber.Clear();
    birthMonth.Clear();
    birthday.Clear();
    write.Close();
    file2.Close();
}

Solution

  • You can't use files like that. They are being opened once only when the class is instantiated. And then at the end of enter_Click() you are closing the file, so the next time you call enter_Click() the file is closed and it fails.

    Create the files inside enter_Click() so that they are opened and closed each time it is called.

    You should use the using keyword to ensure they are closed even if an exception occurs.

    Your code should look more like this:

    private void enter_Click(object sender, EventArgs e)
    {
        using (FileStream file2 = new FileStream(FileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
        {
            using (StreamWriter write = new StreamWriter(file2))
            {
                try
                {
                    friend.FirstName = firstName.Text;
                    friend.LastName = lastName.Text;
                    friend.PhoneNumber = phoneNumber.Text;
                    friend.Month = Convert.ToInt32(birthMonth.Text);
                    friend.Day = Convert.ToInt32(birthday.Text);
                    write.WriteLine(friend.ToString());
                    MessageBox.Show("Wrote " + friend.ToString() + " to file.");
                }
                catch (Exception error)
                {
                    MessageBox.Show(error.Message + " Please reenter the information.");
                }
                firstName.Clear();
                lastName.Clear();
                phoneNumber.Clear();
                birthMonth.Clear();
                birthday.Clear();
            }
        }
    }
    

    There is an alternative way you could handle this - you could open the file once only, and close it only when the class is disposed. Then you could just keep appending to the file without having to keep reopening and closing it.

    I do not recommend doing it that way. It would be more efficient, but it is far far more prone to errors, and if your program crashes there's a danger that the file could have data not written to it - which could corrupt the file.

    It's much better to play it safe and keep opening and closing the file, unless you are writing a lot of data to it; only then might you want to consider this alternative way.