RIESEN textdatei auswerten

  • VB6

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Hamado.

    RIESEN textdatei auswerten

    Schönen guten Tag verehrte Forenleser

    Zu dem Folgenden thema habe ich mich bereits informiert und die Forensuche (auch in anderen Foren) bereits zur genüge zu rate gezogen, jedoch keine gute lösung gefunden.
    Problem ist Folgendes.
    Aus einer 100KB bis 250KB großen Textdatei möchte ich eine bezeichnung auslesen, die mit den zeichen "s00" beginnt. und alle 10 zeichen die dahinter vorkommen ebenfalls mit ausgeben.

    Das Programm hat bereits funktioniert, das heisst, insofern die Datei nicht zu groß ist und der gesamte Text in eine einzelne String Variable passt.
    hier der Quellcode soweit:

    Visual Basic-Quellcode

    1. inhalt = txtReadStr("C:\Struc\IBM\MQS\qmgrs\MSH030T3\errors\test.LOG")
    2. dateiname = Mid(inhalt, InStrRev(inhalt, "s00"), InStrRev(inhalt, ".log") - InStrRev(inhalt, "s00") + 4)
    3. Label1.Caption = dateiname


    Hier die Funktion txtReadStr:

    Visual Basic-Quellcode

    1. Public Function txtReadStr(ByVal sFilename As String) _
    2. As String
    3. Dim F As Integer
    4. Dim sInhalt As String
    5. ' Datei existent?
    6. If Dir$(sFilename, vbNormal) <> "" Then
    7. ' Text binär öffnen und gesamt auslesen
    8. F = FreeFile
    9. Open sFilename For Binary As #F
    10. sInhalt = Space$(LOF(F))
    11. Get #F, , sInhalt
    12. Close #F
    13. End If
    14. txtReadStr = sInhalt
    15. End Function


    Viele der Funktionen die ich verwendet habe waren mir selbst zu beginn des Codens noch nicht bewusst, habe mich wie gesagt schon damit befasst und würde gerne um detaillierte hilfe bitten.
    Danke im Vorraus.

    KLEINE Textdatei auswerten

    So kleine* Dateien kann man noch problemlos am Stück in einen Array lesen

    Visual Basic-Quellcode

    1. Dim strZeile() As String
    2. Open sFilename For Input As #f
    3. strZeile = Split(Input(LOF(f), #f), vbCrLf)
    4. Close #f


    ____________________
    * groß wirds dann, wenn du bei deiner Größenangabe das KB durch MB ersetzt
    Ja, schon richtig.
    aber an derartige größen muss ich jetzt zum glück noch nicht denken und mit dem Fakt, dass die Datei zu groß für eine String Variable ist habe ich ja auch gar nicht so unrecht. ;)

    jedoch 2 Fragen:

    1. Wo du grade die Arrays ansprichst, da muss ich doch die ganze Funktion noch anpassen oder? Wie geh ich das denn am besten an?
    2. wollte ich sowieso noch fragen:
    Da ich sowieso nur den letzten "s00" eintrag in der Textdatei benötige, (stehen ja an die 100 drinnen)
    könnte es sein, dass ich die Textdatei auch von hinten auslesen kann, bis ich den Eintrag gefunden habe?
    Die Funktion sieht dann so aus (beachte die Klammern am Ende des Rückgabewerts)

    Visual Basic-Quellcode

    1. Public Function txtReadStr(ByVal sFilename As String) As String()
    2. Dim F As Integer
    3. Dim strZeile() As String
    4. ' Datei existent?
    5. If Dir$(sFilename, vbNormal) <> "" Then
    6. F = FreeFile
    7. Open sFilename For Input As #f
    8. strZeile = Split(Input(LOF(f), #f), vbCrLf)
    9. Close #f
    10. End If
    11. txtReadStr = strZeile
    12. End Function


    Der Zugriff auf die letzte Zeile geht dann so

    Visual Basic-Quellcode

    1. Dim inhaltArr() as String
    2. inhaltArr = txtReadStr("C:\Struc\IBM\MQS\qmgrs\MSH030T3\errors\test.LOG")
    3. inhalt = inhaltArr(UBound(InhaltArr))
    4. '// oder inhaltArr(UBound(InhaltArr) - 1)
    5. '// je nach dem ob die letzte Zeile mit oder ohne Zeilenumbruch am Schluß ist
    6. dateiname = Mid(inhalt, InStrRev(inhalt, "s00"), InStrRev(inhalt, ".log") - InStrRev(inhalt, "s00") + 4

    ab Dateigrößen von ca 50MB wirds ein bischen langsam (je nach Rechner)

    Nur die letzte Zeile auslesen könnte auch funktionieren, da man ja mit Seek die Leseposition festlegen kann (siehe Bsp in der Hilfe zu Seek)
    Aber dazu mußt du wissen, wo die letzte Zeile beginnt. Wenn die Zeilen alle gleich lang sind kann man das einfach anhand der Dateigröße ausrechnen.
    Rückwärts lesen sollte so auch gehen
    Danke erstmal ich versuche das Auslesen der letzten Zeile in ne schleife mit inkrementierender Variable zu packen, bis der gesuchte Eintrag gefunden wurde.

    Private Sub Command1_Click()

    Visual Basic-Quellcode

    1. Dim InhaltArr() As String
    2. InhaltArr() = txt_ReadAll("C:\Struc\IBM\MQS\qmgrs\MSH030T3\errors\AMQERR01.LOG")
    3. While dateiname = ""
    4. inhalt = InhaltArr(UBound(InhaltArr) - (x + 1))
    5. dateiname = Mid(inhalt, InStrRev(inhalt, "s00"), InStrRev(inhalt, ".log") - InStrRev(inhalt, "s00") + 4)
    6. x = x + 1
    7. Wend
    8. Label1.Caption = dateiname
    9. End Sub

    Schön isses nich, ich weiß ^^"
    übrigens bekomme ich den Fehler: Laufzeitfehler '5' Ungültiger Prozeduraufruf oder ungültiges Argument

    Ich poste zum weiteren Verständnis mal die letzten Zeilen bis zu der, aus der das S0008672.LOG rausgelesen werden soll.

    Brainfuck-Quellcode

    1. ...Protokolldateien, die älter als S0008672.LOG sind, können auf einen
    2. Archivierungsdatenträger gespeichert werden, um Speicherplatz im
    3. Protokollverzeichnis freizugeben.
    4. -------------------------------------------------------------------------------
    5. .


    Hi ein kleineas beispiel mit .net.

    Vieleicht kannste ja was mit anfangen.

    Visual Basic-Quellcode

    1. Dim i, x, zeilen, newtext
    2. Dim TestFile AsString = "c:\liste.txt"
    3. Dim sr As IO.StreamReader = New IO.StreamReader(TestFile)
    4. Dim Text() AsString = Split(sr.ReadToEnd, vbCrLf) 'zeilenweise in Array einlesen
    5. sr.Close()
    6. zeilen = 3
    7. For i = Text.Length - 1 To 0 Step -1
    8. If InStr(1, Text(i), "S00") Then
    9. x = i
    10. For x = i To x + zeilen Step 1
    11. newtext &= Text(x) & vbCrLf
    12. Next
    13. EndIf
    14. Next
    15. MsgBox(newtext)


    Gruß
    Carbe
    nur letzte Zeile auslesen

    Visual Basic-Quellcode

    1. Dim f As Integer
    2. f = FreeFile
    3. Dim strZeile As String
    4. Dim strChar As String
    5. Dim lngAnzahl As Long
    6. Dim lngPos As Long
    7. Open sFilename For Input As #f
    8. '// bei Dateiende minus 2 beginnen, dadurch wird ein
    9. '// evtl vorhandener abschließender Zeilenumbruch
    10. '// ignoriert
    11. For lngPos = LOF(f) - 2 To 1 Step -1
    12. '// Byteweise nach vorne arbeiten
    13. Seek #f, lngPos
    14. '// zwei Bytes lesen
    15. strChar = Input(2, f)
    16. '// Anzahl der Bytes mitzählen
    17. lngAnzahl = lngAnzahl + 1
    18. '// Wenn Zeilenumbruch, dann fertig
    19. If strChar = vbCrLf Then Exit For
    20. Next lngPos
    21. '// letzte Position war der Zeilenumbruch
    22. '// also ist dann plus 2 der Zeilenanfang
    23. Seek #f, lngPos + 2
    24. strZeile = Input(lngAnzahl, f)
    25. Close #f
    26. MsgBox strZeile
    Folgendes...
    Erstmal danke an Carbe. =) Hilft mir leider nicht weiter, aber danke für dein engagement. Find ich klasse.

    Jetzt an Gaga. Erst mal Danke, du bist ne große Hilfe und ich zweifle daran, dass ich die selbe Arbeit auch nur annähernd in der doppelten Zeit hinbekommen hätte. =)
    Jedoch:
    Ich habs eingefügt.
    Ich habe dafür gesorgt, dass er drei Felder durchsucht, ich habe dafür gesorgt, dass er das gesuchte auch Findet (wenn ich "S00" in die zweite Zeile schreibe beispielsweise) ich habe dafür gesorgt, dass alles übergeben und auch ausgegeben wird, aber irgendwie blicke ich noch nicht ganz durch die Befehle durch.
    Kannst du mir noch kurz verraten, was ich anstellen muss oder was ich wo verändern muss, damit der nachdem er die zweite Zeile von unten durchsucht hat eine Zeile höher geht und da weiter sucht? Beziehungsweise, was ich verändern muss, damit er evtl. in der fünften Zeile von unten anfängt?
    Dass der net-Code von Carbe in VB6 nicht funktioniert ist klar...

    Wenn du nicht nur die letzte Zeile lesen willst sondern von hinten an zeilenweise suchen, dann mußt du die For-Schleife die die Zeilenumbrüche sucht noch in eine andere Schleife packen die dann solange durchlaufen wird bis die richtige Zeile gefunden wurde

    Visual Basic-Quellcode

    1. Dim f As Integer
    2. f = FreeFile
    3. Dim strZeile As String
    4. Dim strChar As String
    5. Dim lngAnzahl As Long
    6. Dim lngPos As Long
    7. Dim lngStart As Long
    8. Open sFilename For Input As #f
    9. '// bei Dateiende minus 2 beginnen, dadurch wird ein
    10. '// evtl vorhandener abschließender Zeilenumbruch
    11. '// ignoriert
    12. lngStart = LOF(f) - 2
    13. Do
    14. '// bei jedem Durchlauf der Do-Schleife eine Zeile holen
    15. For lngPos = lngStart To 1 Step -1
    16. '// Byteweise nach vorne arbeiten
    17. Seek #f, lngPos
    18. '// zwei Bytes lesen
    19. strChar = Input(2, f)
    20. '// Anzahl der Bytes mitzählen
    21. lngAnzahl = lngAnzahl + 1
    22. '// Wenn Zeilenumbruch, dann fertig
    23. If strChar = vbCrLf Then Exit For
    24. Next lngPos
    25. '// letzte Position war der Zeilenumbruch
    26. '// also ist dann plus 2 der Zeilenanfang
    27. Seek #f, lngPos + 2
    28. strZeile = Input(lngAnzahl, f)
    29. 'Debug.Print strZeile
    30. '// Hier eben die Bedingung angeben an der du erkennst
    31. '// ob es die gesuchte Zeile ist
    32. If Left$(strZeile, 3) = "xyz" Then
    33. '// richtige Zeile gefunden, äußere Schleife beenden
    34. Exit Do
    35. End If
    36. '// an der zuletzt aktuellen Position minus eins weitermachen
    37. lngStart = lngPos - 1
    38. lngAnzahl = 0
    39. Loop While lngPos > 1 '// spätestens am Dateianfang aufhören
    40. Close #f
    41. MsgBox strZeile
    Ja ne ^^ klar, dass das nich funzt, dass es .net war hab ich ja gemerkt. hab nur gesagt, dass es nicht geholfen hat aber ma was anderes.

    DU BIST EIN GOTT. =D
    Danke. Jetzt ist, wenn ichs im Debug laufen lasse auch alles klar und offensichtlich. War doch sehr informativ.
    Ich und Kollege Danken sehr, der Rest dürfte nicht allzu schwer sein.
    Jetz müssen wir nur noch die Datei mit dem Selben namen zwei ordener weiter unten Finden und alles was numerisch kleiner ist ist löschen.

    Danke für den Support und die schnelle und freundliche Hilfe.