![]() |
Exclusiver Zugriff auf Dateien
Liste der Anhänge anzeigen (Anzahl: 1)
Häufig ist es nötig, exclusiven Zugriff auf eine Datei zu haben.
Wenn z.B. 20 Rechner im Netzwerk in eine Log-Datei schreiben, darf immer nur ein Prozess die Datei offen haben. (siehe auch ![]() Dazu gibt es nun die Klasse TExclusiveFileStream. Zu TFileStream gibt es folgende Unterschiede: * Falls die Datei noch nicht exisitiert, wird sie erzeugt * der Zugriff erlaubt immer Lese- & Schreibzugriff * kein anderer Prozess kann die Datei lesen oder schreiben, solange ein Objekt der Klasse existiert * es kann ein Timeout angegeben werden. Innerhalb dieser Zeit (in ms) wird versucht die Datei zu öffnen/erzeugen. übliche Zeiten liegen zwischen 200ms und 10s. * Während des Wartens, bis die Datei frei wird, wird das Event OnWait "abgefeuert". Dies erlaubt dem Programm, das Warten sichtbar zu machen * Falls die Datei nicht geöffnet werden konnte, enthält die Exception ein aussagekräfte Meldung, warum es nicht geklappt hat TExclusiveFileStream wurde sorgfältig (von mir :-) getestet. Es existiert dazu eine Testanwendung (multithreaded), deren Sourcecode sich im Anhang befindet. Die Funktion GetTickCount wurde so verwendet, dass nach 49,7 Tagen kein Overflow Problem entsteht.
Delphi-Quellcode:
TExclusiveFileStream = class(THandleStream)
private FFileName : string; public constructor Create(const FileName: string; timeout:Cardinal; OnWait:TNotifyEvent=nil); destructor Destroy; override; procedure SeekToEnd; property FileName:string read FFileName; end; { TExclusiveFileStream } constructor TExclusiveFileStream.Create(const filename: string; timeout: Cardinal; OnWait: TNotifyEvent); const FILE_SHARE_EXCLUSIVE = 0; var hnd : THandle; curtime, starttime : Cardinal; error : DWORD; begin FFileName := FileName; starttime := GetTickCount; while true do begin hnd := CreateFile(PChar(filename), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_EXCLUSIVE, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if hnd <> INVALID_HANDLE_VALUE then begin inherited Create(hnd); Exit; end; error := GetLastError; curtime := GetTickCount; if ((curtime - starttime) >= timeout) or ((error<>ERROR_SHARING_VIOLATION) and (error<>ERROR_LOCK_VIOLATION)) then raise EFOpenError.CreateFmt(SFOpenError+#13#10+ SysErrorMessage(error), [FileName]); if Assigned(OnWait) then OnWait(Self); Sleep(100); end; end; destructor TExclusiveFileStream.Destroy; begin if DWORD(Handle) <> INVALID_HANDLE_VALUE then FileClose(Handle); end; procedure TExclusiveFileStream.SeekToEnd; begin Seek(0, soFromEnd); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz