views:

372

answers:

2

Hi all, I am having an issue with SaveFileDialog for some reason. All I want to do is extract data from a text box line by line and write it to a text file, then save that text file to the desktop. The first bit of code works fine (though it doesn't save to the desktop). The second bit of code is what I want to use, but when it creates the text file the text file is empty. What did I do wrong in my second bit of code?

This code works, but it does not save to the desktop and it isn't as nice as the second code.

//When the Save button is clicked the contents of the text box will be written to a text file.
private void saveButton_Click(object sender, EventArgs e)
{
    int textBoxLines = textBox.Lines.Count();
    if (File.Exists(saveFile))
    {
        result = MessageBox.Show("The file " + saveFile + " already exists.\r\nDo you want to replace it?", "File Already Exists!", MessageBoxButtons.YesNo);

        if (result == DialogResult.Yes)
        {
            TextWriter tw1 = new StreamWriter(saveFile);
            for (int i = 0; i < textBoxLines; i++)
            {
                tw1.WriteLine(textBox.Lines.GetValue(i));
            }

            tw1.Close();

        }

        if (result == DialogResult.No)
        {
            MessageBox.Show("Please move or rename existing " + saveFile + "\r\nBefore attempting to save again.", "Message");
        }
    }

    else
    {
        TextWriter tw2 = new StreamWriter(saveFile);
        for (int i = 0; i < textBoxLines; i++)
        {
            tw2.WriteLine(textBox.Lines.GetValue(i));
        }

        tw2.Close();

    }

}

This code does not work, but it is what I want to use.

//When the Save button is clicked the contents of the text box will be written to a text file.
private void saveButton_Click(object sender, EventArgs e)
{
    int textBoxLines = textBox.Lines.Count();

    Stream saveStream;
    SaveFileDialog saveDialog = new SaveFileDialog();
    saveDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
    saveDialog.FilterIndex = 2;
    saveDialog.RestoreDirectory = true;
    saveDialog.FileName = (saveFile);
    saveDialog.InitialDirectory = (Environment.GetFolderPath(Environment.SpecialFolder.Desktop));

    if (saveDialog.ShowDialog() == DialogResult.OK)
    {
        if ((saveStream = saveDialog.OpenFile()) != null)
        {
            StreamWriter tw = new StreamWriter(saveStream);
            for (int i = 0; i < textBoxLines; i++)
            {
                tw.WriteLine(textBox.Lines.GetValue(i));
            }

            saveStream.Close();
        }
    }
}
+4  A: 

You haven't got a tw.Close() after writing the contents. The buffer won't be flushed.

ChrisF
Thanks man, works great now. I used the code here:http://zamov.online.fr/EXHTML/CSharp/CSharp_302155.htmland it didn't have a StreamWriter.Close(), I thought just closing the stream was sufficient. I also noticed that when I put my tw.Close() in the the first time my program crashed because I closed it after I closed the stream, but when I put tw.Close() before saveStream.Close() everything worked fine. Why did it crash the first time?
typoknig
@typoknig - what error did you get when it crashed?
ChrisF
`using` blocks would save a lot of trouble here.
R. Bemrose
I am using the EmguCV library and it isn't debugger friendly. What information it does give me says the following:System.ObjectDisposedException: Cannot access a closed file.at System.Object.IO._Error.FileNotOpen()at System.Object.IO.FileStream.Flush()at System.Object.IO.SystemWriter.Flush(Boolean flushStream. Boolean flush Encoder)at System.Object.IO.StreamWriter.Dispose(Boolean disposing)at System.Object.IO.StreamWriter.Close()and several others similar to these.
typoknig
@typoknig - my best guess would that closing the `Stream` also closes the `StreamWriter` without flushing the buffer.
ChrisF
+2  A: 

As ChrisF noted, you're never closing the SteamWriter. However, as a best practice, you should have using blocks to close/dispose of these for you.

//When the Save button is clicked the contents of the text box will be written to a text file.
private void saveButton_Click(object sender, EventArgs e)
{
    int textBoxLines = textBox.Lines.Count();

    SaveFileDialog saveDialog = new SaveFileDialog();
    saveDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
    saveDialog.FilterIndex = 2;
    saveDialog.RestoreDirectory = true;
    saveDialog.FileName = (saveFile);
    saveDialog.InitialDirectory = (Environment.GetFolderPath(Environment.SpecialFolder.Desktop));

    if (saveDialog.ShowDialog() == DialogResult.OK)
    {
        using (Stream savestream = saveFialog.OpenFile())
        {

            if (saveStream != null)
            {
                using(StreamWriter tw = new StreamWriter(saveStream))
                {

                    for (int i = 0; i < textBoxLines; i++)
                    {
                        tw.WriteLine(textBox.Lines.GetValue(i));
                    }
                }
            }
        }
    }
}
R. Bemrose
Awesome, didn't know that using blocks did that. I'm learning something new all the time here!
typoknig
Yup, using blocks work on anything that implements `IDisposable`. Stream's implementation is documented as calling `Close()` on the Stream in addition to any resource cleanup.
R. Bemrose