Nach vielem rumbasteln habe ich es gesschafft. Es gibt nur ein kleines problem. Der Code sieht so aus:
Delphi-Quellcode:
procedure TForm1.PatchFile(const path, searchFor, replaceWith:string);
var
r,i,j:integer;
f: file of byte;
offset:array of integer;
buf:array [0..8] of byte; //Zu Testzwecken so kurz gehalten
workBuf:array of byte;
begin
ProgressBar.Max := GetFileSizeEx(path);
ProgressBar.Position := 0;
//searchFor -> workbuf
SetLength(workBuf, Length(searchFor));
for i:=0 to Length(workBuf)-1 do
workBuf[i]:=Ord(searchFor[i+1]);
//Durchsuchen
assignfile(f,path);
reset(f);
repeat
blockread(f,buf,Length(buf),r); //Block einlesen
ProgressBar.StepBy(Length(buf));
//buf nach workBuf durchsuchen
for i:=0 to Length(buf)-1 do //buf durchgehen
begin
for j := 0 to Length(workBuf)-1 do //Suchstring bei i durchgehen
begin
if buf[i+j] = workBuf[j] then //Anfang gefunden!
begin
if j = Length(workBuf)-1 then //Komplett gefunden!
{///// PROBLEM: Dies tritt nicht ein wenn der Block in "buf" mitten im Suchstring endet... /////}
begin
SetLength(offset,Length(offset)+1);
offset[Length(offset)-1] := filepos(f) - Length(buf) + i;
//offset[n] gibt die Position des workBuf[0] wieder
end;
end else //Nicht kmoplett gefgunden!
begin
break;
end; //else
end;// for
end;//for
until r < Length(workBuf);
//Alles was gefunden wurde steht in offset...
//Gefundenes ersetztn:
//replaceWith -> als Byte -> workBuf
SetLength(workBuf,Length(replaceWith)+1);
for i:=0 to Length(workBuf)-1 do
workBuf[i] := Ord(replaceWith[i+1]);
//An jedem Offset ersetzen:
for i:=0 to Length(offset)-1 do
begin
Seek(f, offset[i]);
BlockWrite(f, workBuf[0], Length(workBuf),r);
end;
closefile(f);
end;
Hat Spaß gemact das alles so hin zu basteln. nichtmal ein #0 in der Datei stört die Routine.
Nur denke ich das die Suchfunktion endweder viel einfacher geht. Und wenn nicht einfacher, dann brauche ich eine Lösung für das oben beschriebene Problem. Wenn der Suchstring also zwischen 2 "BlockRead(..)" liegt.
Ein anderes problem, eher eine Frage ist: Wieso kann man das Array Buf nicht als Dynamisches array nutzen? Er Meckert dann komischer Weise immer. Denn mit einem Dynamischen Array könnte man auch Dateien die < Length(buf) sind mit dieser Routine bearbeiten.