Question Buit array from .txt file, reset

cemilro

Member
Joined
Nov 19, 2008
Messages
5
Programming Experience
Beginner
Hello all,

I need to compare two arrays built from a .txt file. I've created a class and added a method to read each line and split the strings to create the first array. When the .txt file change, I have to import the second array. But my program continues to read the same old .txt file. Do you know a way to refresh the input .txt file to be able to read the new one? Looking into some MSDN help I've tried to make the class Disposable but I'm not very familiar with OO programming and not sure how to deal with this amazing world of VB.NET.
Can somebody help? Thank you.
 
Hello.

To see the code which you are using to read the input file would be nice. Also, if you close the stream and reopen it, then it should read the 'new' input.

Bobby
 
Built array from text file, reset

This is the part of the code that reads the text file:

VB.NET:
Sub Read_DLU(ByVal path As String)

        Try

            Dim Tempval() As String
            Dim i As Integer, j As Integer, n As Integer, d As Integer
            Dim Miss As String = ""
            Dim Delta_t() As Double
            Dim All_DTC As String = ""
            Dim DTC() As String = New String() {}
            Dim Currentline As String = ""

            'Check existence of the file
            PE.Check_path(path)

            Dim Reader = New myAlias.TextFieldParser(path)

            'Set text fields as Fixed Width
            Reader.TextFieldType = myAlias.FieldType.FixedWidth

            i = 1

            Do While Not Reader.EndOfData

                Dim line_number As Long
                line_number = Reader.LineNumber()

                Try

                    If line_number = 7 Then
                        Data_type = Mid(Trim(Reader.ReadLine), 14, InStr(Reader.ReadLine, " DATA") - 1)
                        'Data_type = Mid(Data_type, 1, Len(Data_type) - 5)       'remove " data" string from data_type
                        
                        'Start getting Rec_nr after the Header
                    ElseIf line_number > 12 Then

                        'Avoid unuseful lines:
                        If Currentline.Contains("") Or Currentline.Contains("MODEL") Or Currentline.Contains("CHECKPASS") Or _
                            Currentline.Contains("TEST") Or Currentline.Contains("NUMBER") Or Currentline = Nothing Then
                            'MsgBox(line_number & " " & Currentline)
                            GoTo read_next_row
                        End If

                        '-----------------------------------------------------------|
                        'When reach "SUMMARY..." row, jump over the rows in-between |
                        'until reach "ALL DATACODES" row                            |
                        If Currentline.Contains("SUMMARY") Then                    '| 
                            '                                                       |
                            Do Until Currentline.Contains("ALL DATACODES")         '|
                                Currentline = Reader.ReadLine                      '|
                            Loop                                                   '|
                        End If                                                     '|
                        '                                                           |
                        '-----------------------------------------------------------|

                        'Get the array of data codes and the total number of DTCs
                        If Currentline.Contains("ALL DATACODES") Then
                            Try
                                Currentline = Reader.ReadLine
                                'Read the remainder of the DLU as a whole
                                All_DTC = Reader.ReadToEnd.Trim
                                MsgBox(All_DTC)

                                'Extract each DTC from the string
                                For n = 0 To All_DTC.Length
                                    ReDim Preserve DTC(n)
                                    DTC(n) = All_DTC.Substring(0, 6)

                                    All_DTC = Right(All_DTC, All_DTC.Trim.Length - 6).Trim
                                    If All_DTC = "" Then
                                        Nr_Of_DTC = n + 1   'Total Number of DTCs
                                        MsgBox(Nr_Of_DTC)
                                        GoTo conclusions
                                    End If
                                Next

                            Catch ex As Exception
                                MsgBox(ex.Message, , "Error after line <ALL DATACODES>!")
                            End Try

                            GoTo conclusions

                        End If

                        'Else, if it's a normal Record row:
                        ReDim Preserve Rec_nr(i)
                        Rec_nr(i) = CInt(Mid(Currentline, 11, 9))
                        'MsgBox(Rec_nr(i))

                        Test_nr = Mid(Currentline, 1, InStr(Currentline, ".") - 1).Trim

                        ReDim Preserve Delta_t(i)
                        Delta_t(i) = CDbl(Mid(Currentline, 47, 18))

                        ReDim Preserve DTC_nr(i)
                        DTC_nr(i) = CInt(Mid(Currentline, 130, 15))
                        'MsgBox(Delta_t(j) & " " & DTC_nr(j))

                        i = i + 1

                    End If

                Catch ex As myAlias.MalformedLineException
                End Try

read_next_row:

                Currentline = Reader.ReadLine

            Loop

conclusions:

[B]reader.close()[/B]

            'Create list of missing records:
            If Rec_nr(1) <> 1 Then Miss = "1"

            For i = 2 To UBound(Rec_nr)

                 d = Rec_nr(i) - Rec_nr(i - 1)

                If d > 1 And d < 1000 Then

                    For j = 1 To d - 1

                        Miss = Miss & ", " & Rec_nr(i - 1) + j

                    Next j

                End If

                'cont_3:

            Next i

            'Remove comma if Miss string starts with comma:
            If Left(Miss, 1) = "," Then
                Miss = Trim(Mid(Miss, 2))
            End If

            'Group_nonprimes (Miss)

            If Miss = "" Then Miss = "None."

            MsgBox(Miss)

            '---------------------------------------------------------------------------
            'Verify the number of DTCs for each record
            For j = 1 To UBound(Rec_nr)
                If DTC_nr(j) <> Nr_Of_DTC Then
                    MsgBox("Rec " & Rec_nr(j) & " might have a different nr of DTCs!")
                End If
            Next
            '----------------------------------------------------------------------------

            If Form1.cbCopy.Checked = True Then
                Copy_file()
            End If

        Catch ex As Exception

            MsgBox(ex.Message, MsgBoxStyle.Exclamation, "Error!")

        End Try

    End Sub


Looking on the Forum through other posts on the subject I learned that Reader.Close () will release the file. I tried that putting this line of code after "conclusions:" and it worked.
Thank you for replying and thank you for the ideas posted here.
 
I have right now not the time to dig through it...but the first thing I saw is this:
VB.NET:
'Avoid unuseful lines:
If Currentline.Contains("") Or

Which is nonsense since it's always true...

Bobby
 
Eek! You redim your arrays every pass of the reader? Do you know what is involved in redimming an array? If your text file contains 1000 lines, youre going to do half a million string copy operations in memory..

Additionally, your comparison routine takes a line and looks for it in every other line of the other array.. Again, your 1000 line files requires 1 million comparisons to determine what to do.

You'd be far better creating a Dictionary(Of String, Object) and setting the values:
dict.Add(line, Nothing)

Then using:
if(dict.ContainsKey(otherLine))
to determine whether your new file contains the same line as an old file

Other minor notes:
File.ReadAllLines() is a much simpler way of reading all the lines in a file

Variable naming conventions in .NET follow the camelCase pattern so for example your variables should look like tempVal, miss, deltaT, allDtc (acronyms of 3+ letters are treated as a word e.g. HttpUrlHandler ), dtc, currentLine

Method naming conventions are PascalCase, e.g. pe.CheckPath(), not PE.Check_path()

Do not use GoTo

Youre declaring int variables to count things that youre storing in a container. There is no need, because you can just ask the container how many items it has. e.g. Dim numOfDtc = myDtcList.Count

Do not use Mid or Right, use string.Substring

Do not use Left, use string.Remove

Do not use Trim, use string.Trim

Do not pick out 1-length substrings and compare them, use the fact that strings are an array of characters. To test the character at index 3:
If "abcd"(3) = "d"c Then 'test if fourth character is a 'd'

Use a StringBuilder when performing many string concatenation operations

Do not use MsgBox, use MessageBox.Show

Do not use CInt, use Convert.ToInt32

Following established conventions helps other developers read your code
 
Last edited:
Built array from text file, reset

Thank you for your time and precious advice!
What is the difference in the way they work, for example CInt and Convert.ToInt32?
 
From cint vs convert.ToInt32 : cint

When someone asks a question like this, I like to take a look at the IL code, since some things that are different language constructs reproduce the same IL code results:

Public Class ILClass

Public Sub Test1()

Dim n As Integer = CInt("5")

End Sub


Public Sub Test2()

Dim n As Integer = Convert.ToInt32("5")

End Sub

End Class


Here is the IL code:

.method public instance void Test1() cil managed
{
// Code size 14 (0xe)
.maxstack 1
.locals init ([0] int32 n)
IL_0000: nop
IL_0001: ldstr "5"
IL_0006: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.IntegerType::FromString(string)
IL_000b: stloc.0
IL_000c: nop
IL_000d: ret
} // end of method ILClass::Test1


.method public instance void Test2() cil managed
{
// Code size 14 (0xe)
.maxstack 1
.locals init ([0] int32 n)
IL_0000: nop
IL_0001: ldstr "5"
IL_0006: call int32 [mscorlib]System.Convert::ToInt32(string)
IL_000b: stloc.0
IL_000c: nop
IL_000d: ret
} // end of method ILClass::Test2

And, here is the code for IntegerType.FromString in the framework:

Public Shared Function FromString(ByVal Value As String) As Integer
Dim num1 As Integer
If (Value Is Nothing) Then
Return 0
End If
Try
Dim num2 As Long
If StringType.IsHexOrOctValue(Value, num2) Then
Return CType(num2, Integer)
End If
num1 = CType(Math.Round(DoubleType.Parse(Value)), Integer)
Catch exception1 As FormatException
Throw New InvalidCastException(Utils.GetResourceString("InvalidCast_FromStringTo", Strings.Left(Value, 32), "Integer"), exception1)
End Try
Return num1
End Function

Here is the code that Convert.ToInt32 calls:

<MethodImpl(MethodImplOptions.InternalCall)> _
Public Shared Function ParseInt32(ByVal s As String, ByVal style As NumberStyles, ByVal info As NumberFormatInfo) As Integer
End Function
 
How can I see the IL code?
Use for example the .Net tool ildasm.exe.
.Net Reflector can also display code in IL language.
 
Back
Top