Search code examples
.netvb.netfilefile-iostreamwriter

How to append data to file using SaveFileDialog


I want to write data to file, so I use SaveFileDialog object:

Public Class Form3
    Inherits Form
    Public callerForm3To1 As Form1

    Dim fileStream As Stream = Nothing
    Dim fileSW As StreamWriter = Nothing

    Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        SaveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
        SaveFileDialog1.FilterIndex = 2
        SaveFileDialog1.RestoreDirectory = True

        FlagWriteToFile = False

        If SaveFileDialog1.ShowDialog() = DialogResult.OK Then
            Btn_writeData.Enabled = True
        End If

    End Sub

   'some code
End Class

And after that I write data to this opened file:

Sub WriteDataToText(data As Long(), appendData As Boolean)
    'Dim a As New StreamWriter(SaveFileDialog1.OpenFile(), FileMode.Append) ' ERROR!
    fileSW = New StreamWriter(SaveFileDialog1.OpenFile())
    If (fileSW IsNot Nothing) Then

        fileSW.WriteLine(String.Join(" ", data) + Environment.NewLine)
        fileSW.Close()
    End If
End Sub

What I want: sometimes I need to append data to this file, and sometimes overwrite. I create appendData for this: if 1 then append if 0 then overwrite. I know I can create StreamWriter for file and use FileMode for my purposes. But If I use SaveFileDialog it's method OpenFile returns Stream! And I cannot create StreamWriter Constructor (it takes String not Stream).

How to append data to file using SaveFileDialog?


Solution

  • You cannot use OpenFile to append data to the file selected in the SaveFileDialog.
    In the MSDN documentation about SaveFileDialog.OpenFile you can read

    For security purposes, this method creates a new file with the selected name and opens it with read/write permissions. This can cause unintentional loss of data if you select an existing file to save to. To save data to an existing file while retaining existing data, use the File class to open the file using the file name returned in the FileName property.

    So you should write your code using the FileName property with the StreamWriter constructor that accepts a boolean True to append data or false to overwrite the file.

    Sub WriteDataToText(data As Long(), appendData As Boolean)
        Using fileSW = New StreamWriter(SaveFileDialog1.FileName, appendData)
            fileSW.WriteLine(String.Join(" ", data) + Environment.NewLine)
        End Using
    End Sub
    

    Remember to always use the Using statement around these disposable object to be sure about correct closing and disposing of the Stream and avoid locking conditions

    Instead using the File class you could write

     Dim newLine = String.Join(" ", data) + Environment.NewLine)
     If appendData Then
         File.AppendAllText(SaveFileDialog1.FileName, newLine)
     else
         File.WriteAllText(SaveFileDialog1.FileName, newLine)
     End If