Hi all,
I have an application that writes sets of data to text files when you click the save button. The each set of data has a heading and the data im saving gets placed under this heading. Everytime you click the save button, my code will check through the existing file to see if the current heading exists. If it does it will attempt to overwrite the old data with the newly saved data under that heading. Problem is.. it appends the data to the end of the file instead of overwriting it!. If ive lost you imagine a file with the following data in it.
Heading1
A
B
C
Heading2
1
2
3
Now say i want to save some changes to the data in Heading2. I now want to have the following data under heading2
Heading2
2
2
3
My code looks something like this:
Private Sub SaveButton_Click()
Dim fs As FileStream
Dim sr As StreamReader
Dim sw As StreamWriter
Dim Heading As String = "Heading2"
fs =
New FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite)sr =
New StreamReader(fs)sw =
New StreamWriter(fs) 'Search through file and find heading, if found write data underneath this heading Do While Not sr.EndOfStreamDataLine = sr.ReadLine
If DataLine = Heading Then sw.WriteLine(2)sw.WriteLine(2)
sw.WriteLine(3)
sw.Close()
Exit Do End If Loopfs.Close()
End Sub
But for some reason it just keeps appending to the end of the file. I know you can set append to False but then i cant use my filestream as my argument, i have to use the filepath. This doesnt work because then i get an error saying the my filepath is already in use by another application (which is my filestream). Im using filestreams rather than textreaders because i need to READ/WRITE one line at a time which i cant seem to do easily with a textreader.
Help please!!
Aaron

Overwriting Data in Text Files
!=MaYHeM
OK thanks...so how do i do that I didnt know you could read through a filestream twice. I thought that once you read through it you couldn't go back.
Michael Thorn
Hi,
Thanks for the reply.
Nope, humans wont be reading the files, but regardless i prefer to use text files rather than binary files since i can actually see if my code is writing the data to the file correctly. Also i dont really know much about binary files and since my text files are so small in size anyway, i dont really see the point in using binary files.
My application has a listbox and quite a few comboboxes/textboxes on one form. The listbox contains a number of items which are my headings. The user can add, delete or modify the data under each of these headings. The data im referring to is the text/index numbers in the textboxes and comboboxes. So at the moment, when the user clicks a heading, the relevant data is loaded into the boxes. My application works fine in this regard, saving and loading data works fine and you can add new headings without problems. Like i was saying earlier, its the modifying thats the problem.
I get what your saying now.. do you mean something like this. Say i have an existing file Test.txt and it has 3 headings, each with 3 lines of data underneath (there will always be 3 lines underneath).
---------------------------------------------------------------------------------------------------------------------------------------------------
Private Sub SaveChanges()
'Define variables
Dim Index As Integer
Dim i As Integer
Dim Count As Integer = 0
Dim Heading As String = "Heading2"
Dim Dataline As String
Dim MyArray As New ArrayList()
Dim fs As Filestream = New FileStream("C:\Test.txt", FileMode.Open, FileAccess.ReadWrite)
Dim ws As Streamwriter = New Streamwriter(fs)
Dim rs As Streamreader = New Streamreader(fs)
'Loop through the file, find the line number of the matching heading and write all the data into an array
Do While Not sr.EndOfStream
Count = Count + 1
Dataline = sr.Readline
If Heading = Dataline Then
Index = Count
End If
MyArray.Add(DataLine)
Loop
sr.Close()
'Delete old file
My.Computer.FileSystem.DeleteFile("C:\Test.txt")
'Open the streamwriter and write the unchanged data and the new data to a new file
For i = 0 To Count
If i <> Index Then
sw.WriteLine(MyArray.Item(i))
Else
sw.WriteLine(Heading)
sw.WriteLine(TextBox1.Text)
sw.WriteLine(TextBox2.Text)
sw.WriteLine(TextBox3.Text)
i = i + 3
End If
Next i
sw.Close()
End Sub
--------------------------------------------------------------------------------------------------------------------------------------------------
I haven't tried this code in VB yet as i'm on a computer that doesnt have it at the moment so i don't know if it works. Is this the basic method you were suggesting The code i just wrote makes sense so i think this is what you were telling me to do. If its not the right way can you please let me know.
I find it pretty strange that you cant simply overwrite data at a specific point in the file. It seems like a pretty standard thing to do. Is it just that you cant read and overwrite data at the same time, or is it a case of not being able to overwrite data at a specific point
Cheers,
Aaron
Chernomor
To insert data into the file you will have to read the whole file into memory, then re-write the file with the newly inserted data. Sorry, there's no way round it.
Edited to add: however, there are XML file format tools which make it easy to add, remove and insert data to files: it may be an option you want to look into.
Kimmie
Something like that, yes. However, you'd want to make it a bit more versatile. You say that 'humans' don't read it, but since it is readable (i personally quite like such text files, for precisely the reason you say), you have to account for the fact that someone may change it, for example, putting an extra blank line in the file.
You wouldn't necessarily need to delete the file, and You'd need to ensure the file is closed before writing to it. Also, rather than putting it all into a single routine, break it out a bit. A routine to read and a routine to write.
ydt
Separate the file access into 3 tasks:
There are several reasons for doing this: it's easy to troubleshoot (which means it will be much more reliable), it's more versatile (If you forget a feature that needs adding to the file, you only have your data interpretation routine to worry about), it's doubly versatile - you can wrapper the operatioons into portable classes for reuse.
In your case, you may want to read the complete file into an array of strings, then rip through those strings, rearranging them, then call the 'writefile' operation (overwriting the existing file).
Things you may want to think about: strings are immutable - how many lines are you going to read Based on your contained data, and the way I'm reading it, maybe a better format for the file may be more efficient (Do humans need to read the file in a text editor)
You can build on the stringreading technique by keeping a 'linenumber' array in addition to the 'string' array, if most of the lines don't change, you can rearrange the line numbers without actually moving the strings (and writing the file based on the linenumbers, not the index in the array). Or, you may want to look at reading the sections in your file into separate classes.