When I read from a .txt file and reach to last line, How can I turn to first line - vb.net

I am reading from txt file line by line and writing to another txt file. When it reach to end, I need to go back to first line. Currently when the code that I wrote reach the last line, it is not turning to first line automatically and not continuing to reading.
I tried to close the file and open it again. I failed with that.
Dim fs As FileStream = New FileStream(dosya, FileMode.Open)
Dim sr As StreamReader = New StreamReader(fs)
Dim fs1 As FileStream = New FileStream(dosya1, FileMode.Append)
Dim sw As StreamWriter = New StreamWriter(fs1)

It looks like you are trying to read lines from one file and repeatedly write them to another. Here are a few ways to accomplish this.
The hard way:
Using sr As New StreamReader(dosya)
Using sw As New StreamWriter(dosya1, True)
For index = 1 To 10
'Read every line from the StreamReader and write to the StreamWriter.
Dim line As String = sr.ReadLine
Do While line IsNot Nothing
sw.WriteLine(line)
line = sr.ReadLine
Loop
'Go back to the beginning of the Stream.
sr.DiscardBufferedData()
sr.BaseStream.Seek(0, System.IO.SeekOrigin.Begin)
Next
End Using
End Using
The simple way:
Dim input As String = File.ReadAllText(dosya)
Using sw As New StreamWriter(dosya1, True)
For index = 1 To 10
sw.Write(input)
Next
End Using
The simplest way (and the least efficient, because with every loop it has to re-read the first file and open the second file for writing):
For index = 1 To 10
File.AppendAllLines(dosya1, File.ReadAllLines(dosya))
Next
#Jimi makes a good remark: if your file is too big to fit in memory, the second and third options might not be usable.

Related

Trying to close textfile after line is read

Im trying to output the data from the second line of my textfile to a datagridview but when doing so it is also outputting every line after the the second line. This is what I have tried. Thanks
Dim lines = IO.File.ReadAllLines(OrderID & ".txt")
For index = 1 To lines.Length - 1
Dim cells = lines(index).Split(","c)
dgvOutput.Rows.Add(cells)
FileClose()
It's outputting every line after the second line, because that's what you're telling it to do when you iterate through the array of strings returns from ReadAllLines.
IO.File.ReadAllLines does not leave an output stream open. The file is closed. What it does do, is return a zero-based (by default) array of the contents of the file, with line breaks being the delimiter for the split.
To just get the contents of the second line, using ReadAllLines, this is what you need:
Dim lines = IO.File.ReadAllLines(OrderID & ".txt")
If lines.length >= 2 Then
Dim cells = lines(1).Split(","c)
dgvOutput.Rows.Add(cells)
End If
Now, that does have the overhead of reading the entire file in. If you open the file using a reader object, then you only need to read the first and second lines of the file to get that second line.
That would be something like this:
Dim reader as StreamReader = My.Computer.FileSystem.OpenTextFileReader(OrderId & ".txt")
Dim a as String
' This reads the first line, which we throw away
reader.ReadLine()
a = reader.ReadLine()
reader.Close()
Dim cells = a.Split(","c)
dgvOutput.Rows.Add(cells)
You would need to test your explicit circumstances to determine which is better for what you're trying to do.
Your loop is executed over all lines skipping just the first line.
While I cannot see what happen in the FileClose call it seems to not have any sense because ReadAllLines has already closed the file.
You can get the second line of your file with a single line of code
Dim line as String = File.ReadLines(OrderID & ".txt").Skip(1).Take(1).FirstOrDefault()
' this check is required to avoid problems with files containing 0 or 1 line
if line IsNot Nothing Then
Dim cells = line.Split(","c)
dgvOutput.Rows.Add(cells)
End If
Notice that I have replaced the ReadAllLines with ReadLines. This is better because using this method you don't read all lines when you need only the second one (if it exists). More info at ReadLines vs ReadAllLines
Dim lines = IO.File.ReadAllLines(OrderID & ".txt")
Dim SecondLine = lines(1)
File.ReadAllLines opens and closes the file for you so there is not need to add code to close it.

Separating large file and inserting carriage returns based on string

New to VB.Net but a friend recommended that I used it for what I'm trying to do. I have a huge text file and I want to insert carriage returns in after a specific string.
Apart from the mess I have below , how would I alter this to read a file and then once we see the text "ext" insert a new line feed. I'm expecting one of the lines in the input file to produce alot of carriage returns.
Currently what I have managed to mock together below reads an input file until end of line and writes it out again into another file.
Module Module1
Sub Main()
Try
' Create an instance of StreamReader to read from a file.
' The using statement also closes the StreamReader.
Using sr As StreamReader = New StreamReader("C:\My Documents\input.txt")
Dim line As String
' Read and display lines from the file until the end of
' the file is reached.
Using sw As StreamWriter = New StreamWriter("C:\My Documents\output.txt")
Do Until sr.EndOfStream
line = sr.ReadLine()
sw.WriteLine(line)
Console.WriteLine("done")
Loop
End Using
End Using
Catch e As Exception
' Let the user know what went wrong.
Console.WriteLine("The file could not be read:")
Console.WriteLine(e.Message)
End Try
Console.ReadKey()
End Sub
Changes made following comments.. Falling over at 500mb files due to memory constraints:
Sub Main()
Try
' Create an instance of StreamReader to read from a file.
' The using statement also closes the StreamReader.
Using sr As StreamReader = New StreamReader("C:\My Documents\input.txt")
Dim line As String
Dim term As String = "</ext>"
' Read and display lines from the file until the end of
' the file is reached.
Using sw As StreamWriter = New StreamWriter("C:\My Documents\output.txt")
Do Until sr.EndOfStream
line = sr.ReadLine()
line = line.Replace(term, term + Environment.NewLine)
sw.WriteLine(line)
Console.WriteLine("done")
Loop
End Using
End Using
Since your lines are very big, you'll have to:
Read/Write one character at a time
Save the last x characters
If the last x characters are equal to your term, write a new line
Dim term As String = "</ext>"
Dim lastChars As String = "".PadRight(term.Length)
Using sw As StreamWriter = New StreamWriter("C:\My Documents\output.txt")
Using sr As New System.IO.StreamReader("C:\My Documents\input.txt")
While Not sr.EndOfStream
Dim buffer(1) As Char
sr.Read(buffer, 0, 1)
lastChars &= buffer(0)
lastChars = lastChars.Remove(0, 1)
sw.Write(buffer(0))
If lastChars = term Then
sw.Write(Environment.NewLine)
End If
End While
End Using
End Using
Note: This will not work with a Unicode file. This assume each characters are one byte.

Visual Basic Append to a specific point in a text file

I am currently trying to manipulate a line in a file that we are using to retain data, using comma delimiters. For example -
121,1212, XJAY,Sean K,Kean S,AAAA-BBBB-AAAA-BBBB-AAAA
12456,987654,WYST,Steve Jobs,Bill Gates,CAAA-BBBB-AAAA-BBBB-AAAA
If I assume that the last line is always a unique code, is it possible to identify that line in the text file and append it with another field?
Prior research has been reading through the APIs for StreamReader and StreamWriter, and looking through other StackOverflow questions, however most questions seem focused on just appending to the end of the file, or in different languages!
As always thank you for your time, and if there is anything I've left off please let me know!
You can't manipulate a line in a file in any reasonably easy way.
There are no methods to work with lines in a file, because files are not line based. They are not even character based. The bytes in the file are decoded into characters, then the line break characters are recognised and the characters can be split into lines.
The easiest way to manipulate a line is to read the entire file into a string array, change the string that you want change, then write the entire string array to the file.
Example:
Dim fileName As String = "c:\data.txt"
Dim lines As String() = File.ReadAllLines(fileName)
For i As Integer = 0 To lines.Length - 1
Dim line As String = lines(i)
If line.StartsWith("12456,") Then
lines(i) = line & ",More data"
End If
Next
File.WriteAllLines(fileName, lines)
If you are looking for a way to parse Each line with StreamReader and StreamWriter: Here it is:
'You will need Imports System.IO
Dim TheNewFile As String
Dim MyLine As String
Dim MyStream2 As New FileStream("C:\Your Directory\YourFile.txt", FileMode.Open)
Dim MyReader As New StreamReader(MyStream2)
Dim MySettings As New StringReader(MyReader.ReadToEnd)
MyReader.BaseStream.Seek(0, SeekOrigin.Begin)
MyReader.Close()
MyStream2.Close()
Try
Do
MyLine = MySettings.ReadLine
'This if statement is an exit parameter. It can be if it contains or if 5 consecutive lines are nothing. It could be a number of things
If MyLine Is Nothing Then Exit Do
'This is the file you will write. You could do if MyLine = "Test" Then ........... append whatever and however you need to
TheNewFile = TheNewFile & MyLine & vbCrLf
Loop
Catch ex As Exception
MsgBox(ex.ToString())
End Try
'-----------------Write The new file!!!----------------
Dim MyStream3 As New FileStream("C:\Where you want to write New File\NewFileName.txt", FileMode.Create)
Dim MyWriter3 As New StreamWriter(MyStream3)
MyWriter3.Write(TheNewFile & "Test")
MyWriter3.Close()
MyStream3.Close()

StreamReader not finding end of file

I simply need to read lines from a text file and show them. When I run this I can see that id does what I want, but after it reads the last value it just shows a blank form on my screen and does not move on. It seems like it can't find the end of the file or something. I don't get an error.
Using sr As New System.IO.StreamReader(Application.StartupPath & "\myfile.cfg")
Dim Line As String = ""
Dim i As Integer = 0
Dim temp_array As Array
Do While Line IsNot Nothing
Line = sr.ReadLine
temp_array = Line.Split("=")
'MessageBox.Show(temp_array(0))
Loop
End Using
That is bad code because you're actually going to use Line before testing whether it's Nothing. Here are two good options for looping through the lines of a text file:
Using reader As New StreamReader(filePath)
Dim line As String
Do Until reader.EndOfStream
line = reader.ReadLine()
'...
Loop
End Using
For Each line In File.ReadLines(filePath)
'...
Next
As you can see, the second is far more concise but it does require .NET 4.0 or later.

Stream Reader and Writer Conflict

I am making a class that is to help with saving some strings to a local text file (I want to append them to that file and not overwrite so that it is a log file). When I write with the streamwriter to find the end of the previous text, I get an error "the file is not available as it is being used by another process". I looked into this problem on MSDN and I got very little help. I tried to eliminate some variables so I removed the streamreader to check was that the problem and it was. When I tried to write to the file then it worked and I got no error so this made me come to the conclusion that the problem arose in the streamreader. But I could not figure out why?
Here is the code:
Public Sub SaveFile(ByVal Task As String, ByVal Difficulty As Integer, ByVal Time_Taken As String)
Dim SW As String = "C:/Program Files/Business Elements/Dashboard System Files/UserWorkEthic.txt"
Dim i As Integer
Dim aryText(3) As String
aryText(0) = Task
aryText(1) = Difficulty
aryText(2) = Time_Taken
Dim objWriter As System.IO.StreamWriter = New System.IO.StreamWriter(SW, True)
Dim reader As System.IO.StreamReader = New System.IO.StreamReader(SW, True)
reader.ReadToEnd()
reader.EndOfStream.ToString()
For i = 0 To 3
objWriter.WriteLine(aryText(reader.EndOfStream + i))
Next
reader.Close()
objWriter.Close()
End Sub
As Joel has commented on the previous answer it is possible to change the type of locking.
Otherwise building on what Neil has suggested, if to try to write to a file with a new reader it is difficult not to lose the information already within the file.
I would suggest you rename the original file to a temporary name, "UserWorkEthicTEMP.txt" for example. Create a new text file with the original name. Now; read a line, write a line, between the two files, before adding your new data onto the end. Finally Delete the temporary file and you will have the new file with the new details. If you have an error the temporary file will serve as a backup of the original. Some sample code below:
Change file names
Dim Line as string
line=Reader.readline
Do until Line=nothing
objwriter.writeline(line)
line=reader.readline
loop
add new values on the end and remove old file
You are trying to read and write to the same file and this is causing a lock contention. Either store the contents of the file into a variable and then write it back out including your new data to the file.
Psuedo
Reader.Open file
String content = Reader.ReadToEnd()
Reader.Close
Writer.Open file
Loop
Writer.Write newContent
Writer.Close