- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
function FileIsBusy(AFileName: string): Boolean;
var
F: Integer;
begin
F := FileOpen(AFileName, fmShareExclusive);
Result := F = -1;
FileClose(F);
end;
function WaitFile(AFileName: string; ASpeepDelay: integer): Boolean;
begin
while FileIsBusy(AFileName) do
Sleep(ASpeepDelay);
Result := True;
end;
пока юзверь ковыряется в Ворде, другой процесс мечтает овладеть файлом
"It is necessary to wait of end of editing Microsoft Office files.I use next conventional approach: file is editing While file is busy" (ингриш - питерского разлива)
это stackoverflow такими сниппетами переполнено
brainstorm 10.12.2010 13:19 # +3
на десктопе? ояебу
bugmenot 10.12.2010 16:23 # 0
ctm 10.12.2010 20:38 # 0
bugmenot 10.12.2010 20:47 # 0
Анонимус 10.12.2010 20:51 # 0
bugmenot 10.12.2010 22:12 # 0
Lure Of Chaos 10.12.2010 13:23 # 0
WGH 10.12.2010 16:09 # 0
bugmenot 10.12.2010 16:21 # 0
WGH 10.12.2010 16:23 # 0
Lure Of Chaos 10.12.2010 16:33 # 0
а раз тут дельфи, значит, скорей всего, для редактирования он порождал новый процесс. Так что тут надо всего лишь дождаться завершения этого процесса
bugmenot 10.12.2010 17:59 # 0
bugmenot 10.12.2010 18:11 # 0
bober_maniac 10.12.2010 23:01 # +1
WGH 11.12.2010 01:11 # −1
bober_maniac 11.12.2010 01:13 # +1
По-нормальному, это делается открытием файла на эксклюзивный доступ однажды - после получения события об изменении файла (точнее, после таймаута событий, потому что они могут идти тоннами, например от ворда) и забыванием про него в случае INVALID_HANDLE до следующего события.
WGH 11.12.2010 01:43 # +1
bober_maniac 11.12.2010 13:16 # 0
WGH 11.12.2010 13:30 # 0
А если программа открывала файл, но так ничего и не изменила?
Я считаю, что в общем случае на винде задача решается только так, так написал автор якобы говнокода.
bober_maniac 11.12.2010 13:32 # 0
WGH 11.12.2010 13:34 # 0
Повторюсь, что в общем случае это не будет работать.
bober_maniac 11.12.2010 13:38 # 0
Можно представить себе приложение, которое после окончания записи будет делать flush, чтобы очистить буферы и вызвать событие изменения файла, потом выжидать полчаса (чтобы враг не догадался) и только потом отпускать файловый дексриптор. В реальной жизни таких программ нет, и сохранение производится двумя способами:
1. Открыл файл, записал, закрыл
2. Создал новый файл, записал в него, переименовал старый в темп, переименовал новый в старый
Алгоритм, который я описываю, покрывает оба этих случая.
bober_maniac 11.12.2010 13:46 # +1
Простой тест на "общий случай" - запись в файл, флаш, ожидание и закрытие файла. Вешаем FSW на систему и смотрим, что нам выведет.
[STAThread]
static void Main(string[] args)
{
FileSystemWatcher fsw = new FileSystemWatcher();
fsw.Path = "D:\\";
fsw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.FileName;
fsw.EnableRaisingEvents = true;
fsw.Filter = "*";
fsw.Changed += new FileSystemEventHandler(fsw_Changed);
Stream s = new FileStream("D:\\test1.txt", FileMode.Create, FileAccess.Write);
s.Write(new byte[500], 0, 500);
s.Flush();
Thread.Sleep(10000);
s.Close();
Console.ReadLine();
}
static void fsw_Changed(object sender, FileSystemEventArgs e)
{
Console.WriteLine("{0}: {1}", e.ChangeType, e.Name);
}
Выводит 2 события Changed. Первое при изменении, второе при закрытии.
WGH 11.12.2010 13:53 # 0
P.S. Жаль, что на MSDN не документированы все тонкости.