Also ich hab das ganze mal testweise in c umgesetzt und glaub das ganze eleganter gelöst zu haben (ohne mit seek zurück zu springen und damit dem erneuten lesen aus Datei).
Leider hab ich grad kein Pascal zur Hand um das ganze nach Pascal zu übersetzen und dann auch zu probieren ob es dann noch funktioniert.
Edit: hier mal mein c-Testcode (sicher noch Verbesserungswürdig)
Code:
static uint32_t fill_buffer(uint32_t *file_pos, char *buffer, uint32_t buf_size, uint32_t keep_len)
{
char file_data[] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz hgfedcba";
uint32_t i;
uint32_t result = 0;
for (i = 0; i < keep_len; i++) {
buffer[i] = buffer[buf_size - keep_len + i];
}
for (i = keep_len; (i < buf_size) && file_data[*file_pos]; i++) {
buffer[i] = file_data[(*file_pos)++];
result++;
}
printf("got bytes from file: %d\r\n", result);
return result;
}
static void func_search_in_file()
{
uint32_t file_pos = 0;
uint32_t i = 0;
uint32_t j;
char *search = "fe";
uint32_t search_len = 2;
char buffer[search_len * 2 + 5];
char *data = &buffer[0];
uint32_t data_len;
data_len = fill_buffer(&file_pos, buffer, sizeof(buffer), 0);
while (1) {
j = 0;
while ((j < search_len) && (data[j] == search[j])) {
j++;
}
if (j == search_len) {
printf("found at: %d\r\n", i);
return;
}
i++;
if (i + search_len > data_len) {
data_len += fill_buffer(&file_pos, buffer, sizeof(buffer), search_len);
data = &buffer[0];
if (i + search_len > data_len) {
printf("not found\r\n");
return;
}
} else {
data = (char*)((uint32_t)data + 1);
}
}
}
[Edit]Ich hab das ganze jetzt mal nach Delphi übersetzt und hoffe dabei nix verhauen zu haben:
[Edit]einige Fehler im Delphi-Quelltext beseitigt
Delphi-Quellcode:
function search_in_file(filename: String; to_find: String): Int64;
var
lStream: TFileStream;
data_len: Cardinal;
search_len: Cardinal;
i: Cardinal;
j: Cardinal;
search: PChar;
data: PChar;
buffer: Array of char;
function fill_buffer(buffer: PChar; buf_size: Cardinal; keep_len: Cardinal): Cardinal;
begin
j := 0;
while (j < keep_len) do
begin
buffer[j] := buffer[buf_size - keep_len + j];
inc(j);
end;
result := lStream.Read(buffer[keep_len], buf_size - keep_len);
end;
begin
lStream := TFileStream.Create(filename, fmOpenRead);
try
i := 0;
search_len := length(to_find);
search := @to_find[1];
SetLength(buffer, search_len * 2 + 1024); //if you have enough memory change the 1024 up to a higher value
data := @buffer[0];
result := -1;
data_len := fill_buffer(@buffer[0], Length(buffer), 0);
while (data_len > 0) do
begin
j := 0;
while ((j < search_len) and (data[j] = search[j])) do
begin
inc(j);
end;
if (j = search_len) then
begin
result := i;
data_len := 0;
end;
inc(i);
if (i + search_len > data_len) then
begin
data_len := data_len + fill_buffer(@buffer[0], Length(buffer), search_len);
data := @buffer[0];
if (i + search_len > data_len) then
data_len := 0;
end
else
data := PChar(Cardinal(data) + 1);
end;
finally
lStream.Free;
end;
end;