Todd432 Todd432 - 23 days ago 15
Vb.net Question

Appending a csv file

Dim NumberOfRecords As Integer

Sub Main()
Call ListTowns()

End Sub

Sub ListTowns()
Dim FileName As String
Dim MyFormat As String = "{0, -22} {1, -16} {2, -8} {3, -8}"
FileName = "Towns.csv"

Dim AllRecords As String() = System.IO.File.ReadAllLines(FileName)

Dim TownList = From record In AllRecords
Let field = record.Split(",")
Select New With {.Name = field(0), .County = field(1), .Population = field(2), .Area = field(3)}

For Each Town In TownList
Console.WriteLine(String.Format(MyFormat, Town.Name, Town.County, Town.Population, Town.Area))
Next
NumberOfRecords = TownList.Count
Console.ReadLine()

End Sub

Sub AddRecord()
Dim FileName As String

FileName = "C:\Users\Omar\Desktop\Towns.csv"
FileOpen(1, FileName, OpenMode.Random)
Dim NewRecord As String


Console.WriteLine("Enter the record you want add")
NewRecord = Console.ReadLine()
FilePut(1, NewRecord, NumberOfRecords + 1)
FileClose(1)
Console.WriteLine("The record has been added")
Console.ReadLine()

End Sub


At the moment the program can list the contents of the csv file however with regard to the
AddRecord()
Sub, when I input the data
Test,Test,Test,Test
it is adding this record to the file properly and is overwriting the first record.

How do I fix this?

Answer

OpenMode.Random is used for reading/writing files that have a fixed width record. It is unclear from your post if you actually have fixed width records (my hunch is you don't). At any rate, to properly read/write in random mode you'd have to declare a structure that defines the length of each record and also tell the system the length of the record when you open it (so that it can move that many bytes to the desired record position you want to read/write!). Follow the links listed in this page titled Random File Access to learn how to do this.

If you don't actually have fixed width records, but instead have variable length records (one record per line, and the lines are different lengths), then you can simply store all the lines in a List(Of String) and add the new record to the end of the List. Now you simply overwrite the entire file with System.IO.File.WriteAllLines(), similar to what you did with ReadAllLines(). With this approach, you can modify any of the records in the List and then simply overwrite the entire file to update the physical file.

Here's a quick example of what the second approach might look like:

Module Module1

    Public AllRecords As New List(Of String)
    Public FileName As String = "C:\Users\Omar\Desktop\Towns.csv"

    Public Sub Main()
        LoadTowns()
        ListTowns()

        AddRecord()

        ListTowns()
    End Sub

    Public Sub LoadTowns()
        AllRecords.Clear()
        AllRecords.AddRange(System.IO.File.ReadAllLines(FileName))
    End Sub

    Public Sub ListTowns()
        Dim MyFormat As String = "{0,  -22} {1,  -16} {2,  -8} {3,  -8}"
        Dim TownList = From record In AllRecords
            Let field = record.Split(",")
                Select New With {.Name = field(0), .County = field(1), .Population = field(2), .Area = field(3)}

        For Each Town In TownList
            Console.WriteLine(String.Format(MyFormat, Town.Name, Town.County, Town.Population, Town.Area))
        Next
        Console.ReadLine()
    End Sub

    Public Sub AddRecord()
        Console.WriteLine("Enter the record you want add")
        Dim NewRecord As String = Console.ReadLine()
        AllRecords.Add(NewRecord)
        System.IO.File.WriteAllLines(FileName, AllRecords.ToArray)
        Console.WriteLine("The record has been added")
        Console.ReadLine()
    End Sub

End Module
Comments