Hallo erstmal
Mein Ziel ist es, eine Textdatei (bzw. eher LogFile) zu öffnen, die bereits in Benutzung ist (Anderes Programm schreibt in die Logfile während ich sie auslese. Per Callback merke ich, wenn die Datei verändert wurde und lade sie somit erneut um auf den aktuellen Stand zu bleiben).
Ich brauche nur einen Lese-Zugriff.
Da die Datei beliebig groß sein soll arbeite ich mit FileOpen und lese somit Byte für Byte die Datei aus. (Lesen größerer Blöcke bringt keine/bzw. eine sehr geringe Veränderung, die durch den Mehraufwand beim analysieren wieder verloren geht.)
Lesen tue ich per FileRead in einen Buffer.
Delphi-Quellcode:
Buffer : PChar;
Buffer:= PChar(AllocMem(1));
FileRead(FileHandle, Buffer^, 1);
Wenn ich das ganze lokal laufen lasse reicht die Geschwindigkeit völlig aus (selbst bei Dateien > 1GB flüssiges Scrollen in der Listbox).
Wenn ich jedoch eine Logfile im Netzwerk (und dafür soll das Programm ja gedacht sein) öffne funktioniert zwar alles, jedoch so langsam, das man damit keinesfalls vernünfig arbeiten kann.
Hier mal ein paar Codeschnipsel:
Öffnen der Datei:
Delphi-Quellcode:
procedure TfrmMain.btOpenClick(Sender: TObject);
begin
if OpenDialog1.Execute then
FilePath:= OpenDialog1.FileName;
if FileExists(Filepath) then
begin
// datei öffnen
FileHandle:= FileOpen(FilePath, fmShareDenyNone);
if FileHandle = -1 then
begin
ShowMessage('Fehler beim Öffnen der Datei!');
Exit;
end;
aBitMapPaint2(pType);
end;
aBitMapPaint2 zeichnet mir ,wie schon gesagt, den gewünschten Teil der Datei in eine ListBox.
FileOpen aus der SysUtils:
Delphi-Quellcode:
uses Windows, SysConst;
function FileOpen(const FileName: string; Mode: LongWord): Integer;
const
AccessMode: array[0..2] of LongWord = (
GENERIC_READ,
GENERIC_WRITE,
GENERIC_READ or GENERIC_WRITE);
ShareMode: array[0..4] of LongWord = (
0,
0,
FILE_SHARE_READ,
FILE_SHARE_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE);
begin
Result := -1;
if ((Mode and 3) <= fmOpenReadWrite) and
((Mode and $F0) <= fmShareDenyNone) then
Result := Integer(CreateFile(PChar(FileName), AccessMode[Mode and 3],
ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0));
end;
Da ich Windows XP benutze habe ich den Teil für Linux herausgenommen.
FileHandle:= FileOpen(FilePath, fmOpenRead or fmShareDenyNone);
Bringt nichts, da ich ja Textdatein im Netzwerk öffnen will und andere Programme auf jeden Fall noch Schreibrechte benötigen.
Testweise habe ich mir FileOpen mal kopiert und FILE_ATTRIBUTE_NORMAL in versch. Werte (FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_HIDDEN, etc (siehe Windows.Pas)) geändert. FILE_ATTRIBUTE_READONLY lies mich die Datei äußerst performant öffnen, jedoch geht mir dabei das Schreibrecht für die anderen Programme verloren.
Ich habe bereits per Google und Suche in versch. Foren nach Lösungsansätzen gefunden, jedoch vergebens.
Das es möglich ist zeigt ja das Programm BareTail, jedoch kann ich dieses nicht für mein Vorhaben verwenden.
Soa, das war eigentlich alles wichtige. Ich hoffe Ihr könnt mir weiterhelfen.
Grüße
Killuah