1

I have a text file with the format:

(title,price,id#)

CD1,11.00,111111
CD2,12.00,222222
CD3,13.00,333333
CD4,14.00,444444
CD5,15.00,555555
CD6,16.00,666666

What is the best way to go change the price of the appropriate CD if I'm given the id# and new price?

I'm sure it has something do to with getting the line and splitting it, but I'm not sure how I edit just one line and not mess up the whole file.

Michael Schilling
  • 341
  • 3
  • 5
  • 16
  • 2
    Will the replacement line be the same size as the existing line? – Jon Skeet Apr 11 '12 at 05:48
  • I would just read it line by line, update the line, if needed, and write it out again line by line. While IO could be reduced, unless it's a *large* file, I would avoid trying to be too clever with seeking and random access, etc. So, with this in mind: *what has been tried*? (And that being said, look up "CSV".) –  Apr 11 '12 at 05:59
  • @MichaelSchilling: And will *every* line be the same length? Is there ever any non-ASCII text? – Jon Skeet Apr 11 '12 at 06:00
  • @JonSkeet not EVERY line, just the price and id# – Michael Schilling Apr 11 '12 at 06:56
  • @pst It will be a small file, probably not more than 25 lines long. What function would you recommend I use for doing that? – Michael Schilling Apr 11 '12 at 06:58
  • Check [this link][1], but you will need to have a minor modification on it. [1]: http://stackoverflow.com/questions/6234119/vb-net-replacing-specific-values-in-a-large-text-file – mrjimoy_05 Apr 11 '12 at 14:31

3 Answers3

2

Okay, now we know it's a short file, life becomes much easier:

  • Load the file into an array of lines using File.ReadAllLines
  • Find the right line using string.Split to split each line into the constituent parts, and check the ID.
  • When you've found the right line, replace it with the complete new line
  • Write the file back with File.WriteAllLines

That should be enough to get you going.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

You can't rewrite a line without rewriting the entire file (unless the lines happen to be the same length). For such a small file it's probably the easiest to change the line in memory and then rewrite all to the file:

Dim idToFind = "444444"
Dim newPrice = "100"
Dim lines = IO.File.ReadAllLines(path)
For i = 0 To lines.Length - 1
    Dim line = lines(i)
    Dim fields = line.Split(","c)
    If fields.Length > 2 Then
        Dim id = fields(2)
        If id = idToFind Then
            Dim title = fields(0)
            lines(i) = String.Format("{0},{1},{2}", title, newPrice, id)
            Exit For
        End If
    End If
Next
IO.File.WriteAllLInes(path, lines)
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
0

If its just a file with like 25 lines, you could do a simple input-transform-output routine and update the price per line.

Something like this (Using Streamreader / writer ).

Sub UpdatePrice(ByVal pricesToUpdate As Dictionary(Of Integer, String), ByVal inputPath As String)
    If Not IO.File.Exists(inputPath) Then Return
    Try
        Using inputStream = New IO.StreamReader(inputPath, System.Text.Encoding.UTF8, True)
            Using outputStream = New IO.StreamWriter(inputPath + ".tmp", False, System.Text.Encoding.UTF8)
                While Not inputStream.EndOfStream
                    Dim inputLine = inputStream.ReadLine
                    Dim content = inputLine.Split(","c)
                    If Not content.Length >= 3 Then
                        outputStream.WriteLine(inputLine)
                        Continue While
                    End If
                    Dim id As Integer
                    If Not Integer.TryParse(content(2), id) Then
                        outputStream.WriteLine(inputLine)
                        Continue While
                    End If
                    If Not pricesToUpdate.ContainsKey(id) Then
                        outputStream.WriteLine(inputLine)
                        Continue While
                    End If
                    content(1) = pricesToUpdate(id)
                    outputStream.WriteLine(String.Join(",", {content(0), content(1), content(2)}))
                End While
            End Using
        End Using
        If IO.File.Exists(inputPath + ".tmp") Then
            IO.File.Delete(inputPath)
            IO.File.Move(inputPath + ".tmp", inputPath)
        End If
    Catch ex As IO.IOException
        If IO.File.Exists(inputPath + ".tmp") Then IO.File.Delete(inputPath + ".tmp")
    End Try
End Sub
Alex
  • 7,901
  • 1
  • 41
  • 56