Форум: "Основная";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];
Внизне допустить чтобы два приложения одновременно запис. и читали фа Найти похожие ветки
← →
domosed © (2005-08-22 01:19) [0]Вот такая задача:
два приложения периодически обращаются к одному и томуже файлу (читают записывают читают записывают читают записывают) вот... есть вероятность что в то время как один попытается записать, другой попытается прочитать что нежелательно. Вот этот вариант правильный или нет:
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);
← →
Defunct © (2005-08-22 02:02) [1]> вариант правильный или нет
нет
← →
tesseract © (2005-08-22 09:58) [2]CreteFile по умолчанию открывает файл как раз в эксклюзивном режиме(если не задавать свойства File_Share_read, File_Share_Write)
← →
Alexander Panov © (2005-08-22 11:32) [3]domosed © (22.08.05 1:19)
А что должна сделать программа в случае возникновения колиизий?
В приведенногм примере возникнет Exception, которое не будет обработано.
← →
domosed © (2005-08-22 17:18) [4]Нужно чтобы пока одно приложение работает с файлом другое просто ждало своей очереди (пока первый его освободит)
Файлы содержат по одной переменной 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;
катит не катит такой вариант
← →
domosed © (2005-08-22 17:23) [5]Да, и вот ещё вопрос появился
Могут ли два приложения просто читать файл одновременно используя простой read(t,x); еще при этом и передвигать указатель Seek(t,123);
← →
Defunct © (2005-08-22 18:45) [6]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: по существу, вопрос синхронизации доступа к одному файлу уже решен множествами СУБД. Используй любую стандартную базу, обеими приложениями.
← →
TUser © (2005-08-22 19:08) [7]Мьютексы, например.
← →
domosed © (2005-08-22 21:05) [8]Про базы данных я абсолютно ничего не знаю:(
Нда примерчик мой действительно не катит. Почемуто виснет на
Hmap:=CreateFileMapping(HFile,nil,PAGE_READWRITE,0,0,nil);
А как тогда без баз данных решить?
← →
Defunct © (2005-08-22 21:27) [9]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) [10]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:31) [11]сори за дубль, что-то в последнее время часто выскакивает..
← →
domosed © (2005-08-23 00:28) [12]Примного благодарен!
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.011 c