Hallo!
Ich kämpfe seit 2 Tagen mit einem Problem beim
Filelocking, für das ich keine Lösung finden kann. Um die Sache klarer zu machen, habe ich alles auf ein einfaches Testprogramm reduziert, wo ich die Schwierigkeit lokalisieren kann:
Ich schreibe z.B. 20.000 Mal 8 Bytes hintereinander in eine neue Datei. Dann setze ich einen
Lock auf irgendeinen Datenbereich dieser 8 Bytes, z.B. beim 1000-sten Satz. Wenn ich dann mit einem zweiten Aufruf dieses Programms (Parallelausführung) auf diese 8 Bytes mit "Lesen_iClick" zugreife (oder auch mit derselben Instanz), kommt genau das erwartete Verhalten: es wird nämlich gemeldet, daß der Bereich gelocked ist. Kurioserweise bekomme ich aber bei den darunterliegenden Daten bei "Lesen_iClick" eine
IOException, obwohl dort gar nichts gelocked ist! Und zwar bis zu einem Bereich von exakt Satz-Nr. 489, also ca. 4096 Bytes unterhalb; ansonsten kann ich normale Lesezugriffe machen (also vom Dateistart an bis zu diesem kritischen Bereich, also bis Satz-Nr. 488, und außerdem direkt oberhalb dem gelockten Bereich, also ab Satz 1001).
Die
IOException würde ja bedeuten, daß etwas gesperrt ist, aber es ist eben NICHTS gesperrt. Trotz aller Versuche kriege ich den Fehler nicht weg! Ich wäre daher für jede Art Hilfe äußerst dankbar.
Hier Teile aus der Source:
Delphi-Quellcode:
type
NRec = record
a,b,c,d,e,f,g,h: byte;
end;
private
N_recsize: integer;
N_Datei: FileStream;
procedure N_Close;
function N_OpenCreate: boolean;
function N_Lock (i:integer): boolean;
function N_UnLock (i:integer): boolean;
function N_Lesen (i:integer; var NSatz:NRec{a,b,c,d,e,f,g,h: byte}): boolean;
procedure N_Locktest (i:integer; bLock:boolean);
...
procedure THaupt2F.N_Close;
begin
try
N_Datei.Free;
except
Msg('# N_close');
end;
end;
function THaupt2F.N_OpenCreate: boolean;
begin
result:=TRUE;
try
N_Datei:=Filestream.Create('test.dat',
FileMode.OpenOrCreate,
FileAccess.ReadWrite,FileShare.ReadWrite);
except
Msg('#OpenorCreate');
result:=FALSE;
end;
N_recsize:=8;
end;
function THaupt2F.N_Lock (i:integer): boolean;
begin
result:=TRUE;
try
N_Datei.Lock(i*N_recsize,1{N_recsize}); {-> der Einfachheit halber nur 1 Byte gelocked}
except
Msg(inttostr(i)+' schon locked');
result:=FALSE;
end
end;
function THaupt2F.N_UnLock (i:integer): boolean;
begin
result:=TRUE;
try
N_Datei.UnLock(i*N_recsize,1{N_recsize}); {-> s.o.}
except
Msg('Unlock '+inttostr(i)+' fail');
result:=FALSE;
end;
end;
procedure THaupt2F.AnlegenSchreibenClick(Sender: TObject);
var i,j: integer;
Writer: BinaryWriter;
Buffer: array [1..8] of byte;
begin
if NOT N_OpenCreate then exit;
Writer:=BinaryWriter.Create(N_Datei);
for i:=0 to 19999 do
begin
for j:=1 to 7 do Buffer[j]:=0; Buffer[8]:=i; { 1 Eintrag }
Writer.Write(Buffer);
end;
N_Close;
end;
function THaupt2F.N_Lesen (i:integer; var NSatz:NRec{a,b,c,d,e,f,g,h:byte}): boolean;
var Reader: BinaryReader;
begin
result:=TRUE;
Reader:=BinaryReader.Create(N_Datei);
with NSatz do
try
N_Datei.Seek(i*N_recsize,SeekOrigin.Begin);
a:=Reader.ReadByte; b:=Reader.ReadByte;
c:=Reader.ReadByte; d:=Reader.ReadByte;
e:=Reader.ReadByte; f:=Reader.ReadByte;
g:=Reader.ReadByte; h:=Reader.ReadByte;
except
on IOException do
begin
Msg('# IOException');
result:=FALSE;
end;
end;
end;
procedure THaupt2F.Lesen_iClick(Sender: TObject);
var i:integer;
NSatz: NRec; {a,b,c,d,e,f,g,h: byte;}
begin
AListe.clear;
try
i:=strtoint(Edit1.Text);
except
exit
end;
if NOT N_OpenCreate then exit;
if N_Lock(i) then
begin
if NOT N_Lesen(i,NSatz{a,b,c,d,e,f,g,h}) then
begin N_close; exit end;
N_UnLock(i);
with NSatz do
AListe.Items.add(a.ToString+' '+
b.ToString+' '+
c.ToString+' '+
d.ToString+' '+
e.ToString+' '+
f.ToString+' '+
g.ToString+' '+
h.ToString);
end;
N_close;
end;
procedure THaupt2F.N_Locktest (i:integer; bLock:boolean);
begin
if bLock then
begin
if NOT N_OpenCreate then exit;
if N_Lock(i) then;
end
else
begin
if N_UnLock(i) then;
N_close;
end;
end;
...
procedure THaupt2F.Lock1000Click(Sender: TObject);
begin N_Locktest(1000,TRUE); end;
...
procedure THaupt2F.UnLock1000Click(Sender: TObject);
begin N_Locktest(1000,FALSE); end;
Die ominöse
Exception tritt beim ersten
Reader.ReadByte in
N_Lesen auf, nachdem das vorangegangene
N_Lock(i) problemlos durchgegangen war.
Ich hoffe, ich habe mich verständlich ausgedrückt, sonst bitte nachfragen!
Grüße
Lothar