How to copy specific lines from an text file to another textfile

topsykretts

Well-known member
Joined
Dec 22, 2011
Messages
47
Programming Experience
Beginner
Hello friends. I am looking to find a way to copy content of specific row from an .txt file to another .txt file but with some changes.
Example:
test.txt
114,114,0
186,206,0
114,206,0
186,114,0
114,100,0
100,114,0

test1.txt
LINE X114 Y206
 
Open a StreamReader on the source file and a StreamWriter on the destination file. Read the lines of the source file in a loop. As you read each one, examine it to determine whether you want to discard it or not. If not, process the data appropriately and then write the result to the destination.

In case you were thinking of asking for the code to do that, I'd like to see you have a go at it first. As should always be the case, you don't do it all at once. The first step would be to open the source file and simply read and display each line. Once you can do that, then it's on to the next step.
 
Open a StreamReader on the source file and a StreamWriter on the destination file. Read the lines of the source file in a loop. As you read each one, examine it to determine whether you want to discard it or not. If not, process the data appropriately and then write the result to the destination.

In case you were thinking of asking for the code to do that, I'd like to see you have a go at it first. As should always be the case, you don't do it all at once. The first step would be to open the source file and simply read and display each line. Once you can do that, then it's on to the next step.
        'Extracting One Line From a File: 
        Dim Tr As IO.TextReader = System.IO.File.OpenText("C:\Users\...\Desktop\test.txt")
        Dim MyFileLine As String = Split(Tr.ReadToEnd(), vbCrLf)(3) 'This return the fourth line from the file
        Tr.Close()
        'MsgBox(MyFileLine)

        Dim str As String
        Dim strArr() As String
        Dim count As Integer
        str = MyFileLine
        strArr = str.Split(",")
        For count = 0 To strArr.Length - 1
            Select Case count
                Case 0
                    Label1.Text = strArr(count)
                Case 1
                    Label2.Text = strArr(count)
                Case 2
                    Label3.Text = strArr(count)
            End Select
        Next
        
        'Creating Text Files:
        'Dim your Text Writer 
        Dim TW As System.IO.TextWriter
        'Create a Text file and load it into the TextWriter 
        TW = System.IO.File.CreateText("C:\Users\...\Desktop\test1.txt")
        'Write a line 
        TW.WriteLine("LINE X" + Label1.Text + " Y" + Label2.Text)
        'Write another line 
        'Flush the text to the file 
        TW.Flush()
        'Close the File 
        TW.Close()

Hello my friend, as you see I wrote code for the one text line from the text file and it works perfect. Now I want to extract other row from the same text file. Is there a way to do it but without new declaration of variables?. Example: Extract one line from(test),modify it, write to (test1) file , after that extract new line from(test) , modify it too, write to (test1) too but below....and few times again,below and below.
 
Last edited by a moderator:
I have added code formatting tags to your post to make the code more readable. Please do so for us in future.

If you had taken my original advice then you'd already be doing what you want. I said to read the lines of the file in a loop. You're not.

This:
VB.NET:
Dim MyFileLine As String = Split(Tr.ReadToEnd(), vbCrLf)(3) 'This return the fourth line from the file
is very, very bad. No doubt you have never read the documentation for that Split method. It says this about the second parameter:
Any single character used to identify substring limits.
You have specified a String containing two characters: a carriage return and a line feed. The method will simply ignore all but the first character in the String, so you're actually splitting on the carriage return only. Some files will use a carriage return and a line feed as a line break and some will use just a line feed but none will use just a carriage return. Your code will fail to split some files altogether and the rest it will leave the line feeds in the lines. Bad, bad, bad!

If you wanted to split the contents yourself then you should at least have called the Strings own Split method. If you want to split a String then ALWAYS call Split on the String itself; NEVER call that Split method and pass the String as an argument. They are two different methods and the one you used is a VB6 hangover. By calling the Split method of the String itself, you have the option of specifying multi-character delimiters and even multiple delimiters. That means that you could specify to split on line feeds and carriage return/line feed pairs, thus supporting all files.

That said, you shouldn't be splitting the String yourself anyway. There are basically three acceptable ways to get the lines of a text file:

1. Create a StreamReader and call ReadLine in a loop. This is what I meant earlier when I said to read the lines of the file in a loop. It will return the file to you one line at a time and keep the file open and locked until the end.

2. Call File.ReadAllLines. It will return the lines of the file to you as a String array and close the file immediately. This allows you random access to the file contents to add, edit and delete lines. Once you're done, you can write the whole lot back to the original file if desired by calling File.WriteAllLines.

3. Call File.ReadLines. It will return the lines to you as an enumerable list of Strings that you can loop through in a read-only, forward-only manner. It will keep the file open and locked until you're done.

Option 2 is often the best when you want to actually edit an existing file because it doesn't lock the file so you can write the new data out without need for a temp file. That becomes an issue for large files though, because you need to store the entire file contents in memory.
 
No doubt you have never read the documentation for that Split method. It says this about the second parameter:
Any single character used to identify substring limits.
That's what the original VB 2003 (.Net 1) docs said, and it carried on to VB 2005 (.Net 2) docs, but in VB 2008 (still .Net 2) docs says:
Any string of characters used to identify substring limits.
This VB runtime function does split by a string delimiter and not only a single char, and it may have changed since .Net 2.

The other options are of course much better for reading lines.
 
That's what the original VB 2003 (.Net 1) docs said, and it carried on to VB 2005 (.Net 2) docs, but in VB 2008 (still .Net 2) docs says:

This VB runtime function does split by a string delimiter and not only a single char, and it may have changed since .Net 2.

The other options are of course much better for reading lines.

Well that is interesting. I just checked the MSDN Library online and every version from .NET 2.0 to 4.5 says the same as the documentation provided with VS 2012, which is "any single character". That said, that same documentation does include examples that show a string being split on a substring and this test of my own:
VB.NET:
Dim str = "ONEabcTWOabcTHREEabcFOUR"
Dim parts = Split(str, "abc")

For Each part In parts
    MessageBox.Show(part)
Next
bears that out. I've never used that Split method so I've never had cause to investigate further but, as with all Runtim functions, it's supposed to behave the same way the corresponding function did in VB6. I guess that's how it worked in VB6 then, which I've also never used.

Regardless, I'd always suggest using String.Split when splitting a String is required, which it's not in this case.
 
Well that is interesting. I just checked the MSDN Library online and every version from .NET 2.0 to 4.5 says the same as the documentation provided with VS 2012, which is "any single character".
Regional differences also then, I guess. Attached screenshot from MSDN online as I see it.
 

Attachments

  • split.png
    split.png
    27.1 KB · Views: 34
Not regional differences apparently. I just searched again and the topic entitled "Split Function (Visual Basic)" lets you choose a VS version and the 2008 version does indeed display as you've shown and, as you say, the older versions specify that it should be a single character. The topic entitled "Strings.Split Method" is for the same method but comes from a .NET perspective rather than a VB perspective and it lets you choose a .NET version. In that case all versions specify a single character. I might notify Microsoft that, out of all the many places that you can read a description for that parameter, one is different to the others and it's the only one that is correct.

I just checked further and, interestingly, the version of the documentation for that method that is VB-oriented stops at VS 2008. If you navigate back to the Functions topic, change the version to 2012 and then navigate down to that function again, you end up at the .NET-oriented version that I mentioned. I guess that you'd have to expect some anomalies in such a vast library as MSDN.
 
Back
Top