Search code examples
arraysvisual-studio-2012iostreamreaderstreamwriter

Reading and Writing Data to Sequential Access Text File


I have an assignment to create a program in Microsoft Visual Studio Express 2012 that opens up a text file that we create and reads a list of names already in it. The program is supposed to take the names and stores them in an array of strings, then display them into a list box. There is also a text box to add a name to an array, when the program closes the program should save the list of names in the array. My main questions are as follows:

  1. How to get the list of names from the array to display upon the program launching

  2. How to add the name from the text box to the already existing array

  3. How to take the array (with the new name in tow) and save it to the file?

It is an online class, the instructor never emails back and we do not have a text book, I have looked around on the web for a while, so I am coming here to see what I can find out.

Here is what I have so far:

Question 1:

Public Class Form1
Dim strReader As System.IO.StreamReader

Private Sub lstNames_SelectedIndexChanged(sender As Object, e As EventArgs)     Handles lstNames.SelectedIndexChanged
    strReader = New IO.StreamReader("Names.txt")
    While (strReader.Peek() > -1)
        lstNames.Items.Add(strReader.ReadLine)
    End While
    strReader.Close()
    Dim nameArray() As String = lstNames.Items.OfType(Of String)().ToArray()
End Sub

Question 2: I do not even know where to begin

Question 3:

Private Sub saveExit_Click(sender As Object, e As EventArgs) Handles    saveExit.Click
    Dim strWriter As New IO.StreamWriter("Names.txt")
    strWriter.Write(lstNames.Text)
    strWriter.Close()
    Application.Exit()
End Sub

Right now the writer will just save over the text file with nothing, as at the moment I haven't been able to get the name array loaded into the list box on start up. Thanks to everyone who comments, I appreciate the help!

Edit: The only problem now is the update listbox information is not saving the data properly, it comes back out as System.String[] here is the code:

  Private Sub saveExit_Click(sender As Object, e As EventArgs) Handles saveExit.Click
    'this converts all items in listbox into strings, then into an array
    Dim names As String() = lstNames.Items.Cast(Of String)().ToArray()
    'This writes the data to the file
    Dim strWriter As IO.StreamWriter = IO.File.AppendText("Names.txt")
    strWriter.WriteLine(names)
    strWriter.Close()
    Application.Exit()
End Sub

Solution

  • Since I do not know what your level of knowledge is, let me start at the beginning.

    1a) You are starting with a Form, and you have several controls on it. The requirement as you have listed it, is that you have to read the file when the program opens. In VS2012, in the designer mode, when you click on the top bar of the form, the properties for the form come up in the property box. In the property panel, along the top edge, you will see a lightening bolt icon. Clicking it will show a list of all the possible events for the selected control (in this case the Form). One of the events is Load. If you double-click on Load it will create a new event handler method for you in the code and jump to it.

    This seems like it would be the best solution for first part of your #1 question.

    1b) As for reading the list from the file, I assume this list is newline delimited? Meaning there is a name on each line. If so, I recommend you take a look at the System.IO in the File class. The ReadLines() method will be very helpful.

    ReadLines() will give you back a collection (or list) of each line in the file. If each name is on a different line, then each item in the collection will be a name.

    1c) Once you have the collection of names, you have to add them to the ListBox. Check out the Items property of the ListBox. The two methods that are going to be helpful for you are Add() and AddRange().

    2) Once you get the names into the list, you can continue to use Add() on the control to update the ListBox. You have a TextBox for entering the new name, and I assume a button which actualy does the add. Again, the Add() method on the ListBox Items property should be useful for that.

    3a) To get the lines back from the ListBox, there are a couple of ways to do that. The one I like the most is using the System.Linq library. Linq is a way in .NET to easily work with collections of objects. Something that is important to note is that the ListBox control Items property contains a collection of Object types. For the visual representation, the ListBox internally calls each object's ToString() method. Obviously if the objects in the collection actually happen to be of type String then it is an easy conversion. That is the case you have here.

    Even so, you'll need the Cast() method call.

    Dim line As String() = listbox.Items.Cast(Of String)().ToArray()
    

    This line will first convert all of the items in the listbox to strings, then convert that list into an array.

    3b) And at last, you can easily write that array back to the file using the WriteAllLines() method in the System.IO.File class.

    UPDATE

    This addresses your question update:

    The File.AppendText() opens a file to add text to it. Your file already has some of the names, and the listbox has all of the names. Append is really not the correct answer.

    Also, since in your example names is a collection, to write the names, you need to loop through them. Note: Best practice is to use the Using statement on objects that have a Dispose() method. These objects implement an Interface called IDisposable. The Using statement has a special relationship with objects that implement IDisposable. It always makes sure that when that End Using line is called, all resources are released.

    Using strWriter As IO.StreamWriter = IO.File.AppendText("Names.txt")
        For Each n As String In names
            strWriter.WriteLine(n)
        Next
        strWriter.Close()
    End Using
    

    A better option would be to use File.WriteAllLines():

    IO.File.WriteAllLines("Names.txt", names)
    

    This one line:

    1. Opens the file for writing. Creates it if it doesn't exist.
    2. Writes each item in the names collection to it's own line in the file.
    3. Closes the file.