Reading and writing lines to and from a file - vb.net

I am writing a simple console application using Microsoft Visual Basic 2010 express. I am trying to make a "newfile1.txt" file in which will be write something heading and than lets say 10 rows with three words in each row.
After that, I would like to read from file, and write to the "newfile2" file only the second word from file "newfile1.txt"
Than I would like to read from this file every line, and store lets and store only the second word from newfile1.txt
I try to use following code but I don't know how to specify several things (see bellow code)
Module Module1
Sub Main()
Dim i As Integer
FileOpen(1, "C:\Users\Namba\Documents\ANALYZA MD\newFile1.txt", OpenMode.Append, OpenAccess.ReadWrite, OpenShare.Default)
FileOpen(2, "C:\Users\Namba\Documents\ANALYZA MD\newFile2.txt", OpenMode.Append, OpenAccess.ReadWrite, OpenShare.Default)
WriteLine(1, "Heading of the file1")
For i = 1 To 10 Step 1
WriteLine(1, "Word 1" & "Word 2" & "Word 3")
Next
FileClose(1)
WriteLine(2, "Heading of the file2")
Dim filereader As System.IO.StreamReader
filereader = My.Computer.FileSystem.OpenTextFileReader("C:\Users\Namba\Documents\ANALYZA MD\newFile1.txt")
Dim stringReader As String
For i = 1 To 10 Step 1
stringReader = filereader.ReadLine()
WriteLine(2, stringReader)
Next
End Sub
End Module
So I have several questions:
Is it possible via ReadLine store words lets say in to the array or each word to the different string variable?
Is there simpler form how to open file and read each word, eventual define that the first word will be store in to the string var1, the second in to the var2 and so on, and similar if we have a file with numbers so that I would like to read from this file and store each number in to the some variable.
I can do this in fortran easy, via READ() WRITE() in very simple way
OPEN(UNIT=11, FILE="newfile1.txt)
READ(UNIT=11) x, y, z
OPEN(UNIT=12, FILE="newfile2.txt)
WRITE(UNIT=12,*) y
So this will read from one file the first 3 word(or number if the x, y, z is declare as number) from the first line and write in to the second file just second word (or number).
So I wonder if there is something very similar also in visual basic?

In general, if your files aren't large then it is faster (with respect to code writing) and easier to just read the contents of the file into memory and then manipulate it as needed.
Hopefully these examples will be of some help.
' Read entire contents of file1.txt into an array.
Dim file1 As String() = System.IO.File.ReadAllLines("C:\file1.txt")
' Now extract the 2nd word from each line (assuming all lines have at least 2 words).
Dim secondWords As New List(Of String)
For Each line In file1
' Break apart the string by spaces and take the second index (word).
secondWords.Add(line.Split(" ")(1))
Next
' Write the contents to a new file.
' This new file will have 1 word per line.
System.IO.File.WriteAllLines("C:\file2.txt", secondWords.ToArray())
If you are looking to examine each word, the code can become something like this:
' Read entire contents of file1.txt into an array.
Dim file1 As String() = System.IO.File.ReadAllLines("C:\file1.txt")
' Process each line.
For Each line In file1
' Process each word within the line.
For Each word In line.Split(" ")
' Do something with the word.
Console.WriteLine(word)
Next
' Or process by word index.
Dim words As String() = line.Split(" ")
For i As Integer = 0 To words.Length - 1
Console.WriteLine(String.Format("Word {0} is {1}", i + 1, words(i)))
Next
Console.WriteLine("Moving to a new line.")
Next

Related

Deleting all lines in text file until you get to a word vb.net

Very new to vb.net, apologies if this is basic. I am trying to open up a text file and delete all the lines starting at index 0 until I hit the line that has the word I am looking for. Right now, it just deletes the word I put in it.
' Read the file line by line
Using reader As New IO.StreamReader(fileName)
While Not reader.EndOfStream()
Dim input As String = reader.ReadLine()
'Delete all lines up to String
Dim i As Integer
i = 0
For i = 0 To input.Contains("{MyWord}")
builder.AppendLine(input)
Next
End While
End Using
Partial. You didn't say what to do with the rest of the lines...
Did you mean lines?
Dim ShouldRead as Boolean
Dim builder As New System.Text.StringBuilder
Using reader As New IO.StreamReader(fileName)
'Delete all lines without String
While Not reader.EndOfStream()
Dim input As String = reader.ReadLine()
If input.Contains("{MyWord}") Then ShouldRead = True
If ShouldRead Then
builder.AppendLine(input)
End If
End While
End Using
I would tend to do it like this:
Dim lines = File.ReadLines(filePath).
SkipWhile(Function(line) Not line.Contains(word)).
ToArray()
File.WriteAllLines(filePath, lines)
The File.ReadLines method reads the lines of the file one by one and exposes them for processing as they are read. That's in contrast to the File.ReadAllLines method, which reads all the lines of the file and returns them in an array, at which case you can do as desired with that array.
The SkipWhile method will skip the items in a list while the specified condition is True and expose the rest of the list, so that code will skip lines while they don't contain the specified word and return the rest, which are then pushed into an array and returned. That array is then written back over the original file.
Just note that String.Contains is case-sensitive. If you're using .NET Core 2.1 or later then there is a case-insensitive overload but older versions would require the use of String.IndexOf for case-insensitivity.

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.

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()

Reset index of File object for reading several time

Now, I am writing a VBA program. In my program, firstly I need to count all line from a file. I need line count because of creating array for line in file. So, I used this code. It is OK.
'Open file
Set file = fsObject.OpenTextFile(filePath, ForReading)
'Read all line
file.ReadAll
'Get line count
lineCount = file.line
'Close file
file.Close
After getting line count, I want to subtract 2 from it for header and footer(the blank line). I don't know which word will be header. I only know row that they are first row and last row(the blank row).
'Remove header and blank line from line count
lineCount = lineCount - 2
And then, I wanna read that file line by line which are only useful for me and store all line in array. The problem is at that, when reading line by line, It is need to re-open file. Only after re-open, I can read line by line.
Because, "ReadAll" method is readed all line and the index of file object is shown "AtEndOfFile". So, I must re-open it. Please check my code.
'If line count is greater than 0, read again file to get data
If lineCount > 0 Then
'Re-define array size
ReDim lineList(lineCount) As String
'Here I opend it, I don't wanna open. I just want to set index of file object.
'Re-open file
Set file = fsObject.OpenTextFile(filePath, ForReading)
'Read file until end
Do Until file.AtEndOfStream
'If current line is not first line(header) or last line(blank line)
If line <> 0 And line <= lineCount Then
'Store line into array
lineList(index) = file.ReadLine
'Increase array index
index = index + 1
Else
file.ReadLine
End If
'Increase line index
line = line + 1
Loop
End If
But, I want another way. I don't wanna re-open file. I want to reset the index to the first line of file object. So, I don't need to re-open it.
I already search about it in internet. But, I didn't found any suggestions for that. Please help me. Thanks.
My approach is slightly different than your current approach, I would use the Binary read to read the file and save it in a temporary string, then use Split function to put them in an Array.
This method has one drawback as in the if the length (number of characters) of the file is greater than the size of a String variable then we might have issues but other than that. This is quite different approach.
Public Sub ReadFileData(filePath As String, Optional separatorStr As String = ";#;")
'******************************************************************************
' Opens a large TXT File, reads the data until EOF on the Source,
' then stores them in an Array
' Arguments:
' ``````````
' 1. The Source File Path - "C:\Users\SO\FileName.Txt" (or) D:\Data.txt
' 2. (Optional) Separator - The separator, you wish to use. Defauls to ';#;'
'*******************************************************************************
Dim strIn As String, tmpStr As String, lineCtr As Long
Dim tmpArr() As String
Open filePath For Input As #1
Do While Not EOF(1)
'Read one line at a time.
Line Input #1, strIn
tmpStr = tmpStr & Trim(strIn) & separatorStr
lineCtr = lineCtr + 1
Loop
Close #1
tmpArr = Split(tmpStr, separatorStr)
Debug.Print "Number of Elements in the Arrays is - " & UBound(tmpArr)
Debug.Print "Number of Lines Read is - " & lineCtr
End Sub

Words from text file as variables in a checkedlistbox

I have discovered how to take a text file and put it in an checkedlistbox. Now I want to apply variables to each item in the checkedlistbox also using a text file.
This is the code I used.
Imports System.IO 'Top of the source code
Dim sr As New StreamReader("C:\Users\Me\Desktop\test.txt")
Dim word As String = ""
Dim words(9) As String
Dim i As Integer = 0
Do Until sr.Peek = -1
word = sr.ReadLine()
words(i) = word
Vlanbx1.Checklisbox.Items.Add(words(i))
Vlanbx2.Checklisbox.Items.Add(words(i))
i = i + 1
Loop
I would like to have both the checkedlistbox items and the variables in the same text file side by side.
My main goal is to have a list that when it is changed in the text file is updates when the form is opened. But I am unsure how to grab the variables to the text and apply them to their adjacent Items from the list.
Any guidance, please.
Your code works without problem only if your file has no more that 10 lines.
You could change it in this way
Imports System.IO
....
Dim words = File.ReadLines("C:\Users\Me\Desktop\test.txt").ToList()
For Each word in words
Vlanbx1.Checklisbox.Items.Add(word)
Vlanbx2.Checklisbox.Items.Add(word)
Next
Now the File.ReadLines returns all the lines of your file in a List(Of String) then you could loop over this List and add the words one by one to your CheckedListBoxes
EDIT
Following your comment, if you have a line composed of two words separated by a space and the first word should be stored in the checkedlistbox while the second one in a internal list of words, then your code should change to
Imports System.IO
....
Dim listOfSecondWords = new List(Of String)()
Dim lines = File.ReadLines("C:\Users\Me\Desktop\test.txt").ToList()
For Each line in lines
Dim words = line.Split(" "c)
Vlanbx1.Checklisbox.Items.Add(words(0))
Vlanbx2.Checklisbox.Items.Add(words(0))
listOfSecondWords.Add(words(1))
Next
A bit of error control should be added to be really sure that you have two words for each line checking the length of the array words obtained splitting the line at the first space character