Letztes Zeichen (ein chr(12)) aus Textfile löschen

  • Hallo,

    ich möchte das letzte Zeichen einer Textdatei löschen. Bei diesem Zeichen handelt es sich um ein FormFeed (CHR(12)). Wenn ich das Zeichen mittels StringRight ($text = StringReplace($text, StringRight($text, 1), "")) ersetze, werden auch die FormFeeds auf den vorherigen Seiten gelöscht.

    danke

    oliver

    Einmal editiert, zuletzt von O1iverH (28. Oktober 2012 um 10:32)

  • Hi,

    die spektakulärere Lösung wäre:

    [autoit]

    #include <file.au3>

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

    $in = "input.txt"
    $out = "output.txt"

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

    $cnt = _FileCountLines($in)

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

    for $i = 1 to $cnt
    if $i < $cnt then
    FileWriteLine($out,FileReadLine($in,$i))
    Elseif $i = $cnt Then
    FileWriteLine($out,StringMid(FileReadLine($in,$cnt),1,StringLen(FileReadLine($in,$cnt))-1))
    EndIf
    Next

    [/autoit]

    Gruß
    x0r

    Simon nörgelt, Simon nervt - aber Simon verbessert die Welt. Glaubt er.

  • Cleverer wäre es, anstatt die ganze Datei einzulesen und neu zu schreiben, sie einfach nur im Dateisystem um ein Zeichen zu kürzen.
    Dies wäre deutlich fixer:

    [autoit]

    #include <WinAPI.au3>

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

    Global Const $s_FilePath = @ScriptDir & "\Test.txt"

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

    Global $h_File = _WinAPI_CreateFile($s_FilePath, 2, 4) ; Datei öffnen
    If $h_File = 0 Then Exit MsgBox(48, "Fehler", "Konnte Datei nicht öffnen/finden")

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

    _WinAPI_SetFilePointer($h_File, -1, $FILE_END) ; Zeiger auf vorletztes Zeichen der Datei setzen
    _WinAPI_SetEndOfFile($h_File) ; Datei an aktueller Zeigerposition trimmen
    _WinAPI_CloseHandle($h_File)

    [/autoit]
  • Hi AspirinJunkie,

    bei ner Datei mit 1.86mb Größe dauert meins um die 49sec.

    Deins braucht 0.00085sec.

    Glaub ich muss mir doch mal "WinAPI" anschauen ;)

    Gruß
    x0r

    Simon nörgelt, Simon nervt - aber Simon verbessert die Welt. Glaubt er.


  • bei ner Datei mit 1.86mb Größe dauert meins um die 49sec.

    Deine Lösung ist auch denkbar ungünstig, da:
    1. Für _FileCountLines wird die Datei gelesen und gezählt.
    2. Für FileReadLine wird ein Teil der Datei eingelesen, nach dem Zeilenende gesucht und sie dann geschlossen.
    3. Zudem verwendest du viele Funktionen, die die Lesbarkeit deutlich erschweren.
    4. Es wird abwechselnd gelesen und geschrieben, Ein- und Ausgabe muss also eine andere Datei sein.

    Die Methode von Blowcake ist da deutlich besser.

    Die, von AspirinJunkie hat natürlich den Vorteil, dass es nicht nur schnell ist, sondern die Dateigröße nicht für die Geschwindigkeit relevant ist, und auch Arbeitsspeicher gespart wird. Man kann z.B. auch 10 GB große Dateien bearbeiten, auch mit einem 32-bit System.

  • @xor
    Marthog hat Recht.
    Deine Umsetzung ist etwas unglücklich was vor allem an der Verwendung von FileReadLine liegt.
    Das Problem ist das du bei FileReadLine mit der Zeilennummer arbeitest (und daher vorher ein FileCountLines benötigst).
    Wie die Hilfe zu Filereadline aber schon sagt sollte man dies tunlichst vermeiden.
    Schau dir einfach mal in der AutoIt-Hilfe zu FileReadLine das Beispiel an wie es dort gemacht wird.
    Damit benötigst du kein FileCountLines mehr und auch ansonsten sollte das ganze deutlich performanter werden.
    Wenn du dann noch bei FileWriteLine statt mit dem Dateinamen mit einem FileHandle von FileOpen (nur einmal vor der Schleife öffnen) arbeitest wäre dann auch der zweite Flaschenhals beseitigt.

  • Hi,

    mein Schwerpunkt liegt (bis jetzt) nicht auf Schnelligkeit und/oder Resourcenersparnis, sondern rein auf Funktion.

    Bei kleineren Dateien funktionierts tadellos, auch wenns etwas suboptimal ist, Funktion steht wie gesagt im Vordergrund (dementsprechend gibts auch keine komplexen Scripte).

    Schnell in 2 Minuten einen 4-Zeiler geschrieben und 13 Minuten laufen lassen, funktioniert für mich besser als in 14 Minuten so ein riesen Teil und 1 Minute Laufzeit :)
    (für Sachen, die man sowieso nur 1x machen muss)

    P.S.: Schätze ich sollte mein Sicht der Dinge irgendwann mal ändern :D

    Gruß
    x0r

    Simon nörgelt, Simon nervt - aber Simon verbessert die Welt. Glaubt er.