Problem mit variadischer Funktion Topic is solved

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

mike65
Posts: 11
Joined: 18 Oct 2019, 11:08

Problem mit variadischer Funktion

Post by mike65 » 03 Jan 2021, 07:36

Hallo liebe AHK-Community,

ich stehe mal wieder vor einem Problem bei dem ich nicht weiter komme.

Mit folgender Funktion will ich eine Kopie von sehr großen Textdateien erzeugen. In der neu erstellten Kopie der Textdatei sollen auch noch bestimmte Zeichen ersetzt werden.

Die Anzahl der zu ersetzenden Zeichen variiert, weshalb ich eine variadische Funktion gewählt habe. (im folgenden Beispiel mit 3 optionalen Parametern)

Hier also erstmal das Programm:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

Pfad := "C:\Windows\Temp\"
Originaldatei := "test.txt"

Ersetzen(Pfad,Originaldatei,"A|B","E|F","X|Y")		; A soll durch B ersetzt werden, E -> F etc...

Ersetzen(Pfad,Originaldatei,oParams*){		
oFile := FileOpen(Pfad . Originaldatei, "r")			; Datei lesend öffnen
oEditFile := FileOpen(Pfad . "test2.txt", "w")			; Neue Datei erzeugen & schreibend öffnen
Loop, % oParams.Length()							; Schleife über alle vorhandenen optionalen Ersetzungsparameter
	{
		oFile.Pos := 0								; Zeiger (wieder) auf Anfang
		oEditFile.Pos := 0							; Zeiger (wieder) auf Anfang
		aReplace := StrSplit(oParams[A_Index], "|")	; Ersetzungsparameter in Array speichern / z.B.  aReplace[1]=A   aReplace[2]=B
		While !oFile.AtEOF						; in Schleife zeilenweise die Zeichen ersetzen falls vorhanden
			{
				Str_Renamed := oFile.ReadLine()	
				Str_Renamed := StrReplace(Str_Renamed, aReplace[1], aReplace[2], ErsetzteVar)
				if (ErsetzteVar!=0) 						; Debug / zur Info was ersetzt wird
					msgbox % Str_Renamed 					; Debug / zur Info was ersetzt wird
				oEditFile.Write(Str_Renamed)			; hier muss der Fehler sein weil nur der letzte Durchlauf geschrieben wird / was fehlt?
			}
	}
oEditFile.Close()
oFile.Close()
return
}
Hier die Original Textdatei (einfach jede Zeile ein Buchstabe A-Z)

Code: Select all

A
B
C
D
E
F
G
H
I
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
Mein Problem ist nun dass immer nur der letzte Ersetzungsparameter (X ersetzt durch Y) in der neu geschriebenen Datei ersetzt wurde anstatt alle drei Parameter.

Über eure Hilfe würde ich mich sehr freuen
just me
Posts: 7744
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Problem mit variadischer Funktion  Topic is solved

Post by just me » 03 Jan 2021, 09:20

Moin,

Dein Problem besteht darin, dass

Code: Select all

Str_Renamed := oFile.ReadLine()	
jedesmal die Originaldatei liest und die Änderungen dann nach oEditFile (über)schreibt.

Außerdem denke ich, dass es deutlich schneller wäre, die Datei komplett einzulesen und alle Ersetzungen in einem Rutsch anzuwenden.

Wenn das nicht möglich ist, solltest Du wenigstens alle Ersetzungen in einem Rutsch auf jeden Satz anwenden.
mike65
Posts: 11
Joined: 18 Oct 2019, 11:08

Re: Problem mit variadischer Funktion

Post by mike65 » 03 Jan 2021, 09:53

just me wrote:
03 Jan 2021, 09:20
Moin,

Dein Problem besteht darin, dass

Code: Select all

Str_Renamed := oFile.ReadLine()	
jedesmal die Originaldatei liest und die Änderungen dann nach oEditFile (über)schreibt.

Außerdem denke ich, dass es deutlich schneller wäre, die Datei komplett einzulesen und alle Ersetzungen in einem Rutsch anzuwenden.

Wenn das nicht möglich ist, solltest Du wenigstens alle Ersetzungen in einem Rutsch auf jeden Satz anwenden.

Super ich danke dir :bravo: , ich habe es jetzt so gelöst:

Code: Select all

Ersetzen(Pfad,Originaldatei,oParams*){		
oFile := FileOpen(Pfad . Originaldatei, "r")			; Datei lesend öffnen
oEditFile := FileOpen(Pfad . "test2.txt", "w")			; Neue Datei erzeugen & schreibend öffnen
While !oFile.AtEOF
	{
		Str_Renamed := oFile.ReadLine()		
		Loop, % oParams.Length()			
			{
				aReplace := StrSplit(oParams[A_Index], "|")
				Str_Renamed := StrReplace(Str_Renamed, aReplace[1], aReplace[2])
			} Until A_Index = oParams.Length
		oEditFile.Write(Str_Renamed)
	}
oEditFile.Close()
oFile.Close()
msgbox done
return
}
Da die Textdateien sehr groß sind (>1GB) will ich sie nicht komplett in den Arbeitsspeicher laden, darum diese Lösung.
just me
Posts: 7744
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Problem mit variadischer Funktion

Post by just me » 03 Jan 2021, 10:13

Ok, wenn - wie ich in diesem Fall annehme - durch die Ersetzungen keine Zeilenumbrüche vermurkst werden können, kannst Du Deine großen Dateien auch häppchenweise verarbeiten. Das FileObject ist dafür ideal und Du nutzt es ja ohnehin schon:

Code: Select all

Happen := 4*1024*1024 ; <<<<<<<<<< 4 MB pro Happen
While !oFile.AtEOF
{
		Str_Renamed := oFile.Read(Happen)   ; <<<<<<<<<<
		Loop, % oParams.Length()
			{
				aReplace := StrSplit(oParams[A_Index], "|")
				Str_Renamed := StrReplace(Str_Renamed, aReplace[1], aReplace[2])
			} Until A_Index = oParams.Length
		oEditFile.Write(Str_Renamed)
}
Das sollte schneller gehen.
Post Reply

Return to “Ich brauche Hilfe”