Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

August 25, 2009

Reading Fixed Length Files: TextFieldParser

Filed under: Text Files,VB.NET @ 5:05 pm

In my prior post, I covered how to read a fixed length file into an in-memory DataTable. You could then work with the DataTable as desired to access the fields from the file. You could even bind the resulting DataTable to a grid or other control.

But sometimes you just need to process the file line-by-line and need a simpler solution. That is where the TextFieldParser class comes in.

The TextFieldParser works with any file extension and with any character set, so you can use it with UTF-8 or ANSI text files.

For this example, the text file is as follows:

000001  Baggins             Bilbo     20090811
000002  Baggins             Frodo     20090801
000003  Gamgee              Samwise   20090820
000004  Cotton              Rosie     20090821

NOTE: Be sure to set a reference to Microsoft.VisualBasic.FileIO

Since this class is part of the Visual Basic namespace, only the VB code is presented here. However, you can import this namespace in a C# program and use it.

Dim fileName As String = "testFixed.txt"
Dim dirName As String = _
     Path.GetDirectoryName(Application.ExecutablePath)

Using tf As New TextFieldParser _
            (Path.Combine(dirName, fileName))
 
   tf.TextFieldType = FileIO.FieldType.FixedWidth
    tf.SetFieldWidths(6, 22, 10, 8)

    Dim row As String()
    While Not tf.EndOfData
        Try
            row = tf.ReadFields()
            For Each field As String In row
                ‘ Do whatever to the set of fields
                Debug.WriteLine(field)
            Next

        Catch ex As MalformedLineException
            MessageBox.Show("Line " & ex.Message & _
            "is not valid and will be skipped.")
        End Try
    End While
End Using

This code first declares variables to hold the text file name and the directory name. The file can reside in any directory that the user can access. In this example, the file resides in the same directory where the application is executed. But this is not a requirement.

The first using statement in the example code creates an instance of the TextFieldParser class. The parameter to the constructor defines the directory and filename of the text file. The Path.Combine method is used to ensure that the correct slashes are added to the end of the directory name as required.

The code then sets two additional properties. The first is TextFieldType. Since this is a fixed width file, the FixedWidth type is specified. The second is SetFieldWidths. This defines the widths of each column in the text file.

The While loop processes each line of the file. The ReadFields method reads each row of the file into a string array. If there is a problem reading the line, the Try/Catch block catches the error, displays a message and continues. (However, in a real application you would want to log this information instead of displaying it to the user.)

The For/Next statement loops through the fields in the row and displays them. This is where you would add the code that processes the values from the text file.

Notice that as you go through each loop, you replace the row variable with the field from the next line. So after a row is processed, you cannot access the data from that row again. (If you do need more random access to the data, you can store each row in a list or other structure, or you can read the data into a DataTable using the technique detailed here.)

The resulting information in the Debug window is as follows:

000001
Baggins
Bilbo
20090811
000002
Baggins
Frodo
20090801
000003
Gamgee
Samwise
20090820
000004
Cotton
Rosie
20090821

Enjoy!

8 Comments

  1.   Jan — July 2, 2010 @ 3:45 pm    Reply

    Deborah,

    I am very proud of you for being so thorough and detailed explanation about how to read fixed length file. I therefore have a very clear concept.

    Thanks a million, Deborah.

  2.   Bob — August 17, 2010 @ 4:09 pm    Reply

    Deborah I am learning VB6 and am working on a project that needs to read comma separated text and recognize them as numbers. The text file I am using to test the code is on the root of C: drive and is named Text.text and has many lines that look like this with 10 characters on each line: 10, 252, 23, 4, 15, 160 , 7. 82, 12, 43. Max character length is 3.

    How do I use your code to find my text file on C: and then convert each set of comma separated text into a numeric value?

    Any help is most appreciated

  3.   DeborahK — August 17, 2010 @ 7:03 pm    Reply

    Hi Bob –

    May I ask why you are learning VB6? It has long since passed its support period by Microsoft. And VB 2010 is free! (Visual Basic 2010 Express Edition.)

    The code here is for VB.NET.

    For assistance on VB 6 projects, check out this post:

    http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/6a0719fe-14af-47f7-9f51-a8ea2b9c8d6b

    Good luck!

  4.   Tony Girgenti — September 22, 2010 @ 7:17 am    Reply

    Hello Deborah.

    Is there a way to modify this code to process variable rows of text each with different field column widths?

    For instance, a row with a “0” in column 1 has four columns and a row with a “1” in column 1 has six columns.

    Thanks,
    Tony

  5.   DeborahK — September 22, 2010 @ 12:07 pm    Reply

    Hi Tony –

    Would it be possible to define the file such that it has the maximum number of columns (6 in your example) and that the rows with four columns fill two with nothing? Then the above code should work.

    But with a complex structure, formatting the file as XML may be easier. Do you have control over the incoming text file?

  6.   Tony Girgenti — September 22, 2010 @ 3:18 pm    Reply

    Hello Deborah.

    I do have control over the incoming text file. Actually, I’m not sure if you realize this, but I am communicating with you about documenting this project. I’m suffering from coding withdrawal symptoms and I feel like I wanted to do some coding for this project before finishing the design of it. I know this is not the right thing to do, but it is just killing me to find out how I will be doing this project in VB.

    I am actually the creator of the incoming text file. It gets created by a COBOL program on an HP3000 computer. The file contains fixed length records of 900 bytes. Each record is terminated by CR/LF. The problem is that the records have about ten different formats. I don’t always use the full 900 bytes for each record type.

    The fields are not always the same length from record to record. Some records only have two fields (a control code and 80 characters of text). Other records have numerous fields each containing dates, numbers or text.

    Thanks for any help that you can provide.

    Tony

  7.   AndyB — January 18, 2013 @ 12:19 pm    Reply

    This rocks!!! Thank you!!! Worked Perfectly!!!

  8.   NABIL ABDULAAL — January 17, 2017 @ 11:49 pm    Reply

    Thanks for this example, is there any update which might be more advanced under VB .Net 2013/2015 ? Thanks again

RSS feed for comments on this post. TrackBack URI

Leave a comment

© 2023 Deborah's Developer MindScape   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs