![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
не допустить чтобы два приложения одновременно запис. и читали фа [D6]
domosed © (2005-08-22 01:19:00)Вот такая задача:
два приложения периодически обращаются к одному и томуже файлу (читают записывают читают записывают читают записывают) вот... есть вероятность что в то время как один попытается записать, другой попытается прочитать что нежелательно. Вот этот вариант правильный или нет:
AssignFile(t,'xxx.xxx');
rewrite(t);
repeat
write(t,x);
until IOResult=0;
CloseFile(t);
{а в это время приложение номер 2 пытается сделать следующее}
AssignFile(t,'xxx.xxx');
reset(t);
repeat
read(t,x);
until IOResult=0;
CloseFile(t);
domosed (2005-08-23 00:28:00) [1]Примного благодарен!
Defunct (2005-08-22 21:31:00) [2]сори за дубль, что-то в последнее время часто выскакивает..
Defunct (2005-08-22 21:27:00) [3]domosed © (22.08.05 21:05) [8]
Чес слово, базы не настолько сложны, чтобы их шарахаться. Впору начинать читать статьи по работе с базами данных. Рекомендую Interbase, для не на мой взгляд в делфи самая удобная обвязка.
> А как тогда без баз данных решить?
> два приложения периодически обращаются к одному и томуже файлу (читают записывают читают записывают читают записывают)
Пример:
const
ASharedFile = '1.txt';
{$R *.dfm}
procedure ExclusiveWrite( var Buf; count: integer);
var
Stream : TFileStream;
Captured : boolean;
begin
Captured := false;
if not FileExists( ASharedFile ) then
TFileStream.Create( ASharedFile, fmCreate).Free;
// ждем разрешения доступа
while not Captured do
try
Stream := TFileStream.Create( ASharedFile, fmOpenWrite or fmShareDenyWrite);
Captured := True;
except
Captured := false;
sleep(10);
end;
// записываем
Stream.Position := Stream.Size;
Stream.Write( Buf, Count );
Stream.Free;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
S : String;
begin
S := 'date = ' + FormatDateTime('dd-mm-yyyy hh:nn:ss', Now ) +
'(process id = ' + IntToHex( GetCurrentProcessId, 8 ) + ')' +
#13+#10;
ExclusiveWrite( S[1], Length(S) );
end;
Разултат выполнения трех одновременно запущенных программ:
date = 22-08-2005 20:26:34(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
C чтением быть по аналогии.
Defunct (2005-08-22 21:27:00) [4]domosed © (22.08.05 21:05) [8]
Чес слово, базы не настолько сложны, чтобы их шарахаться. Впору начинать читать статьи по работе с базами данных. Рекомендую Interbase, для не на мой взгляд в делфи самая удобная обвязка.
> А как тогда без баз данных решить?
> два приложения периодически обращаются к одному и томуже файлу (читают записывают читают записывают читают записывают)
Пример:
const
ASharedFile = '1.txt';
{$R *.dfm}
procedure ExclusiveWrite( var Buf; count: integer);
var
Stream : TFileStream;
Captured : boolean;
begin
Captured := false;
if not FileExists( ASharedFile ) then
TFileStream.Create( ASharedFile, fmCreate).Free;
// ждем разрешения доступа
while not Captured do
try
Stream := TFileStream.Create( ASharedFile, fmOpenWrite or fmShareDenyWrite);
Captured := True;
except
Captured := false;
sleep(10);
end;
// записываем
Stream.Position := Stream.Size;
Stream.Write( Buf, Count );
Stream.Free;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
S : String;
begin
S := 'date = ' + FormatDateTime('dd-mm-yyyy hh:nn:ss', Now ) +
'(process id = ' + IntToHex( GetCurrentProcessId, 8 ) + ')' +
#13+#10;
ExclusiveWrite( S[1], Length(S) );
end;
Разултат выполнения трех одновременно запущенных программ:
date = 22-08-2005 20:26:34(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
date = 22-08-2005 20:26:35(process id = 0000095C)
date = 22-08-2005 20:26:35(process id = 00000A0C)
date = 22-08-2005 20:26:35(process id = 00000FA8)
C чтением быть по аналогии.
domosed (2005-08-22 21:05:00) [5]Про базы данных я абсолютно ничего не знаю:(
Нда примерчик мой действительно не катит. Почемуто виснет на
Hmap:=CreateFileMapping(HFile,nil,PAGE_READWRITE,0,0,nil);
А как тогда без баз данных решить?
TUser (2005-08-22 19:08:00) [6]Мьютексы, например.
Defunct (2005-08-22 18:45:00) [7]domosed © (22.08.05 17:18) [4]
> катит не катит такой вариант
второе.
domosed © (22.08.05 17:23) [5]
> Могут ли два приложения просто читать файл одновременно используя простой read(t,x); еще при этом и передвигать указатель Seek(t,123);
Могут. при FileMode = 1
но лучше воспользоваться:
TFileStream.Create( fFileName, fmOpenRead or fmShareDenyNone );
либо
TFileStream.Create( fFileName, fmReadWrite or fmShareDenyNone );
PS: по существу, вопрос синхронизации доступа к одному файлу уже решен множествами СУБД. Используй любую стандартную базу, обеими приложениями.
domosed (2005-08-22 17:23:00) [8]Да, и вот ещё вопрос появился
Могут ли два приложения просто читать файл одновременно используя простой read(t,x); еще при этом и передвигать указатель Seek(t,123);
domosed (2005-08-22 17:18:00) [9]Нужно чтобы пока одно приложение работает с файлом другое просто ждало своей очереди (пока первый его освободит)
Файлы содержат по одной переменной integer
Пока придумал такой ещё вариант
{запись}
procedure writef(var filename:string; dat:integer);
var HFile,HMap:THandle;
Adrbase:^integer;
begin
repeat
HFile:=FileOpen(filename,fmOpenReadWrite or fmShareExclusive);
until HFile<>0;
repeat
Hmap:=CreateFileMapping(HFile,nil,PAGE_READWRITE,0,0,nil);
until Hmap<>0;
repeat
Adrbase:=MapViewOfFile(HMap,FILE_MAP_WRITE,0,0,0);
until not(Adrbase=nil);
AdrBase^:=dat;
UnmapViewOfFile(AdrBase);
CloseHandle(HMap);
CloseHandle(HFile);
end;
{чтение}
procedure readf(var filename:string;out dat:integer);
var HFile,HMap:THandle;
Adrbase:^integer;
begin
repeat
HFile:=FileOpen(filename,fmOpenReadWrite or fmShareExclusive);
until HFile<>0;
repeat
Hmap:=CreateFileMapping(HFile,nil,PAGE_READWRITE,0,0,nil);
until Hmap<>0;
repeat
Adrbase:=MapViewOfFile(HMap,FILE_MAP_WRITE,0,0,0);
until not(Adrbase=nil);
dat:=AdrBase^;
UnmapViewOfFile(AdrBase);
CloseHandle(HMap);
CloseHandle(HFile);
end;
катит не катит такой вариант
Alexander Panov (2005-08-22 11:32:00) [10]domosed © (22.08.05 1:19)
А что должна сделать программа в случае возникновения колиизий?
В приведенногм примере возникнет Exception, которое не будет обработано.
tesseract (2005-08-22 09:58:00) [11]CreteFile по умолчанию открывает файл как раз в эксклюзивном режиме(если не задавать свойства File_Share_read, File_Share_Write)
Defunct (2005-08-22 02:02:00) [12]> вариант правильный или нет
нет