Einzelnen Beitrag anzeigen

Killuah

Registriert seit: 18. Okt 2007
6 Beiträge
 
Delphi 2006 Architect
 
#1

FileOpen mit fmShareDenyNone zu langsam

  Alt 18. Jul 2008, 10:00
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
  Mit Zitat antworten Zitat