Bytelänge von Textzeile herausfinden

  • Hallo Community,

    ich habe folgende Funktion um aus einer Datei etwas zu lesen

    [autoit]

    $sFile = @ScriptDir & "\test.txt"
    $tBuffer = DllStructCreate("byte[6]")
    $hFile = _WinAPI_CreateFile($sFile, 2, 2)
    _WinAPI_SetFilePointer($hFile, 0)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), 6, $nBytes)
    _WinAPI_CloseHandle($hFile)
    $sText = BinaryToString(DllStructGetData($tBuffer, 1))
    ConsoleWrite($sText & @CRLF)

    [/autoit]

    Mein Problem ist aber Jetzt, dass:
    Ich aus einer Datei nur eine bestimmte Byte-Länge lesen kann , da sich aber in meiner Datei unterschiedlichlange Textzeilen befinden kommt da immer was sehr wüstes raus :D

    z.b. will ich aus einer Datei lesen die Folgendes enthält:

    [autoit]

    0
    1
    0.1
    0.2
    etc.

    [/autoit]

    Natülich muss man die Funktion noch in eine For-Schleife packen damit man alles auslesen kann.

    manchmal kommt dann sowas raus:

    [autoit]

    0
    10
    .1
    0
    .2
    etc.

    [/autoit]


    Wie kann ich das jetzt am besten gestalten bzw. wie kann ich herausfinden wieviele Bytes ich in einer Textzeile habe AUßER mit FileReadLine o.ä. denn das ist mir zu langsam.

  • AUßER mit FileReadLine o.ä. denn das ist mir zu langsam


    Bist du sicher dass du FileReadLine richtig benutzt?
    Ich vermute mal ganz stark, dass du die Zeilennummer als zweiten Parameter einträgst und in der Schleife hochzählen lässt.
    Das muss natürlich furchtbar langsam sein.
    Wenn du es so machst wie im Beispiel in der Hilfe zu FileReadLine (also ohne die Zeilennummer einzutragen, sondern einfach die Datei Zeile für Zeile durchgehen) ist das ganze alles andere als langsam.

  • Ich denke mal das ich FileReadLine richtig benutze, aber wenn man eine datei mit bis zu 1 Millionen zeilen hat dauert das schon ziemlich lange.

    Zum vergleich mit FileWrite habe ich für diese bis zu 1 Millionen Zeilen mehrere Stunden gebraucht, mit der WinAPI habe ich nur etwa ein paar sekunden gebraucht. Dasselbe will ich jetzt auch für das auslesen der Datei machen nur weiß ich nicht genau wie ich das anstellen soll.

    Die Funktion zum in die Datei schreiben ist diese hier:

    [autoit]

    $tBuffer = DllStructCreate("byte[" & StringLen($sText) & "]")
    DllStructSetData($tBuffer, 1, $sText)
    $hFile = _WinAPI_CreateFile($sFile, 1)
    _WinAPI_WriteFile($hFile, DllStructGetPtr($tBuffer), StringLen($sText), $nBytes)
    _WinAPI_CloseHandle($hFile)

    [/autoit]
  • Ich denke mal das ich FileReadLine richtig benutze, aber wenn man eine datei mit bis zu 1 Millionen zeilen hat dauert das schon ziemlich lange.

    Zum vergleich mit FileWrite habe ich für diese bis zu 1 Millionen Zeilen mehrere Stunden gebraucht, mit der WinAPI habe ich nur etwa ein paar sekunden gebraucht. Dasselbe will ich jetzt auch für das auslesen der Datei machen nur weiß ich nicht genau wie ich das anstellen soll.

    Die Funktion zum in die Datei schreiben ist diese hier:

    [autoit]

    $tBuffer = DllStructCreate("byte[" & StringLen($sText) & "]")
    DllStructSetData($tBuffer, 1, $sText)
    $hFile = _WinAPI_CreateFile($sFile, 1)
    _WinAPI_WriteFile($hFile, DllStructGetPtr($tBuffer), StringLen($sText), $nBytes)
    _WinAPI_CloseHandle($hFile)

    [/autoit]
  • Zum vergleich mit FileWrite habe ich für diese bis zu 1 Millionen Zeilen mehrere Stunden gebraucht, mit der WinAPI habe ich nur etwa ein paar sekunden gebraucht.

    Dann benutzt du auch FileWrite/Line nicht richtig.
    Bei mir erstellt es mit FileWriteLine eine Datei mit einer Million Zeilen in 1,1 Sekunden:

    Spoiler anzeigen
    [autoit]

    Global Const $s_TargetFile = "C:\Test.txt"
    Global Const $s_LineString = "Dies ist meine Testzeile Nummer "
    Global Const $N = 1e6

    [/autoit] [autoit][/autoit] [autoit]

    Global $iT, $h_File

    [/autoit] [autoit][/autoit] [autoit]

    $iT = TimerInit()
    $h_File = FileOpen($s_TargetFile, 2)
    For $i = 1 To $N
    FileWriteLine($h_File, $s_LineString & $i)
    Next
    FileClose($h_File)
    $iT = TimerDiff($iT)
    ConsoleWrite(StringFormat("%15s:\t%7.3f ms\n", "Zeitdauer", $iT))

    [/autoit]


    Langsam wird es erst wenn man den Hinweis aus der Hilfe zu FileWriteLine einfach überliest und statt einem Handle den Dateinamen übergibt:

    Spoiler anzeigen
    [autoit]

    Global Const $s_TargetFile = "D:\Test.txt"
    Global Const $s_LineString = "Dies ist meine Testzeile Nummer "
    Global Const $N = 1e3

    [/autoit] [autoit][/autoit] [autoit]

    Global $iT, $h_File

    [/autoit] [autoit][/autoit] [autoit]

    $iT = TimerInit()
    $h_File = FileOpen($s_TargetFile, 2)
    For $i = 1 To $N
    FileWriteLine($h_File, $s_LineString & $i)
    Next
    FileClose($h_File)
    $iT = TimerDiff($iT)
    ConsoleWrite(StringFormat("%15s:\t%7.3f ms\n", "Mit FileOpen()", $iT))

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    FileDelete($s_TargetFile)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Mit dauerndem Neuöffnen der Datei durch FileWrite:
    $iT = TimerInit()
    For $i = 1 To $N
    FileWriteLine($s_TargetFile, $s_LineString & $i)
    Next
    $iT = TimerDiff($iT)
    ConsoleWrite(StringFormat("%15s:\t%7.3f ms\n", "Ohne FileOpen()", $iT))

    [/autoit]
  • Hab das jetzt ausprobiert. Das Funktioniert jetz so schnell wie ich es will, aber wenn ich das jetzt mit FileRead statt FileWrite mache dann ist das wieder sehr langsam.

    [autoit]

    $hFile = FileOpen($sFile)
    For $i = 0 To $Width - 1 Step 1
    For $i2 = 0 To $Height - 1 Step 1
    $a[$i][$i2] = FileReadLine($hFile,$Line)
    $Line += 1
    Next
    Next
    FileClose($hFile)

    [/autoit]

  • Bist du sicher dass du FileReadLine richtig benutzt?
    Ich vermute mal ganz stark, dass du die Zeilennummer als zweiten Parameter einträgst und in der Schleife hochzählen lässt.
    Das muss natürlich furchtbar langsam sein.
    Wenn du es so machst wie im Beispiel in der Hilfe zu FileReadLine (also ohne die Zeilennummer einzutragen, sondern einfach die Datei Zeile für Zeile durchgehen) ist das ganze alles andere als langsam.

    Hast du das gelesen?
    Du sollst den zweiten Parameter von FileReadLine() nicht verwenden! Du brauchst $Line gar nicht.

  • Zitat von AutoIt Hilfe

    [...] Wenn keine Zeilennummer zum Lesen angegeben wurde, wird die "nächste" Zeile eingelesen (die "nächste" bedeutet bei einer neu geöffneten Datei die erste Zeile). [...]