sehr große Textdatei mit Autoit einlesen

  • Hallo,

    ich lese per Autoit mit der Funktion "FileReadLine" sehr große Textdateien ein und schreibe diese in ein Array, um damit per Autoit-Gui weiter zu arbeiten.
    Nun sind diese Textdateien leider sehr groß und das Einlesen dauert mehrere Minuten, da unter anderem der PC an dem das ganze später laufen sollte, nur eine alte WinXP Maschine 32bit ist, diese kann ich aber leider nicht tauschen....

    Hat jemand vielleicht eine Idee wie man dieses einlesen und trennen der Strings beschleunigen könnte? Mit dem Trennen meine ich, dass ich jede Zeile nach vorkommenden "=" mit "StringSplit" in eine separate Spalte des Array einlese.


    Komischerweise funktioniert die dazu passende Gui nach dem einlesen sehr flüssig, aber da ist die Datei ja schon im Array bzw. im RAM
    Die Dateien haben im Durchschnitt zwischen 20000-100000 Zeilen und sind mehrere MB groß.

    Danke für jeden Vorschlag!!!


    Spoiler anzeigen

    Func _GetLinesToArray($hFilePfad, ByRef $obj)
    Local $i = 0, $line, $aSplit, $bSplit[4]
    Local $CountLines
    Global $Delimiter1 = '=', $Delimiter2 = '"'
    Local $option = 0; "$Delimiter2" am Anfang und am Ende des Strings abschneiden (kann zu Fehlern führen)


    ;~ MsgBox("262144","",$hFile)
    If $hFilePfad = -1 Then
    MsgBox("262144", "Fehler", "Konnte Datei nicht öffnen.")
    Return False
    Else
    $CountLines = _FileCountLines($hFilePfad)
    ReDim $obj[$CountLines + 1][3]


    For $i = 1 To $CountLines
    ;~ MsgBox("262144",$i,$CountLines)
    $line = FileReadLine($hFilePfad, $i)
    If @error = -1 Then
    MsgBox("262144", $i, "Fehler!! - ExitLoop")
    ExitLoop
    ElseIf @error = 1 Then ;wenn kein $Delimiter gefunden wurde
    MsgBox("262144", $i, "Fehler!! - ContinueLoop")
    ContinueLoop
    Else
    $aSplit = StringSplit($line, $Delimiter1) ;2 Spalten im Array: 1=Wert vor dem $Delimiter, 2= Wert danach
    ;~ redim $bSplit[4];array vergrößern
    If $aSplit[0] >= 2 Then ;= wurde öfter als einmal gefunden
    $bSplit[0] = $i
    $bSplit[1] = $aSplit[0];Anzahl Treffer
    $bSplit[2] = $aSplit[1]


    If $aSplit[0] = 2 And $aSplit[2] = "" Then
    $bSplit[3] = $Delimiter1 ;wird keine Zeichen nach einem $Delimiter gefunden, gehöhrt diese mit zum Text
    Else
    $bSplit[3] = StringTrimLeft($line, StringLen($aSplit[1]) + StringLen($Delimiter1)) ;= und Folgetext gemeinsam
    EndIf
    If $option = 1 Then
    If StringLeft($bSplit[3], 1) = $Delimiter2 Then ; Wenn das erste Zeichen ein "=" ist
    $bSplit[3] = StringTrimLeft($bSplit[3], 1) ;löscht erstes Zeichen, wenn ein "
    EndIf
    If StringRight($bSplit[3], 1) = $Delimiter2 Then ; gibt letztes Zeichen zurück
    $bSplit[3] = StringTrimRight($bSplit[3], 1);löscht erstes Zeichen, wenn ein "
    EndIf
    EndIf
    Else
    $bSplit[0] = $i
    $bSplit[1] = $aSplit[0];Anzahl Treffer
    $bSplit[2] = $aSplit[1]
    $bSplit[3] = ""
    EndIf
    EndIf
    ;~ DebugArray($bSplit,"$bSplit")
    $obj[$i - 1][0] = ""
    $obj[$i - 1][1] = $bSplit[2]
    $obj[$i - 1][2] = $bSplit[3]
    Next
    EndIf
    ;~ MsgBox("262144","test",$hFilePfad)
    ;~ DebugArray($obj,"$obj")
    FileClose($hFilePfad) ;Schließe Dateizugriff:


    EndFunc ;==>_GetLinesToArray

  • Datei klein: Jetzt 0.16 Sekunden
    Datei groß: Jetzt 0.78 Sekunden


    Wenn du Zeilen einzeln einließt, wie du es gemacht hast, und dabei keinen Filehandle benutzt, wird die Datei für jede Zeile geöffnet und ausgelesen, die entsprechende Zeile herausgesucht und zurückgegeben. Das dauert!
    Zum einlesen gibt es extra die FileReadToArray() Funktion. Ansonsten ginge es so:

    AutoIt
    $hFile=fileopen($file)
    while 1
    	;Bei einem Filehandle wird automatisch immer die nächste zeile genommen (siehe Hilfe), 
    	;bei einem String (Dateipfad) wird die Datei jedesmal neu geöffnet.
    	$line=FileReadLine($hFile)
    	if @error then ExitLoop
    	;was mit der ziele passieren soll
    WEnd
    FileClose($hFile)

    Ich hoffe, das hilft dir weiter :)

    MfG Kanashius