Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   FileOpen mit fmShareDenyNone zu langsam (https://www.delphipraxis.net/117447-fileopen-mit-fmsharedenynone-zu-langsam.html)

Killuah 18. Jul 2008 10:00


FileOpen mit fmShareDenyNone zu langsam
 
Hallo erstmal :hi:

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.

Delphi-Quellcode:
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

Bernhard Geyer 18. Jul 2008 10:07

Re: FileOpen mit fmShareDenyNone zu langsam
 
Nimm mal größere Lesepuffer. Bei 1 Byte könnte ich mir schon Performanceprobleme vorstellen.

Killuah 18. Jul 2008 10:37

Re: FileOpen mit fmShareDenyNone zu langsam
 
Macht aber wie schon gesagt keinerlei Unterschiede, da ich mir merke, an welcher Stelle im Dokument ich gerade bin und auch nur den anzuzeigenden Teil auslese.

SirThornberry 18. Jul 2008 10:55

Re: FileOpen mit fmShareDenyNone zu langsam
 
Dann machst du etwas falsch. Das langsamste Glied ist fast immer die Festplatte. Kleine Stückenlesen dauert da einfach länger als ein großes weil die Position neu angesprungen werden muss etc.
Und wenn du dann ein großes Stück im Speicher hast kann man das bedeutend schneller durchlaufen als auf der Festplatte.

Killuah 18. Jul 2008 11:16

Re: FileOpen mit fmShareDenyNone zu langsam
 
Das Performance-Problem besteht auch nur bei einem fmSharexxx, wenn ich etwas über das Netzwerk damit lese.
Das es bei einem neuen Server an der Hardware liegt kann ich mir nur sehr sehr schlecht vorstellen.

edt: Werds trotzdem nochmal Testen...


Nachdem ich nun einige Routinen ausgebessert habe scheint alles so zu laufen wie ich möchte. Anscheinend hab ich mir irgendwo nen großen Ast in die Speichen geworfen. :coder2:


Danke trotzdem für die schnelle Hilfe. :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:22 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz