Forth
http://fforum.winglion.ru/

Как определить что "файл занят другим процессом"?
http://fforum.winglion.ru/viewtopic.php?f=18&t=2710
Страница 1 из 2

Автор:  registration [ Ср фев 23, 2011 19:19 ]
Заголовок сообщения:  Как определить что "файл занят другим процессом"?

Прежде всего спасибо, WingLion, за активацию аккаунта.
У меня вопрос, на который на форуме nnCron я не смог получить четкий ответ, поэтому спрашиваю здесь.

Как средствами SP-Forth (или nnCron) определить определить что "файл занят другим процессом" или свободен?
ОС Windows XP

Файл формируеся на разделяемом сетевом ресурсе, произвольной машиной в сети.
Алгоритм желаемых действий nnCronа примерно такой:

При появлении нужного файла в папке проверять,
ЕСЛИ файл занят ТО ждать ИНАЧЕ выполнять с ним действие.

WatchFile для файлов размером больше 0,2 Мб срабатывает дважды:
1-й раз при появлении файла в папке,
2-й раз после того как он полностью скопируется.
в результате nnCron или выдает ошибку "файл занят другим процессом" или
вылолняет действие над файлом который ещё не полностью скопировался.

Автор:  F-MAP [ Чт фев 24, 2011 13:11 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

Цитата:
Как средствами SP-Forth (или nnCron) определить определить что "файл занят другим процессом" или свободен?
ОС Windows XP

Возможно один из вариантов, пробовать переименовать или переместить файл в цикле функцией (spf4.20)
Код:
WINAPI: MoveFileA KERNEL32.DLL
: RENAME-FILE ( from-a1 u1 to-a2 u2 -- ior)
DROP NIP SWAP MoveFileA ERR ;

ior - подскажет, если не ноль, что то не так, вроде 5 или 12 занят другим процессом

Автор:  Alexander [ Чт фев 24, 2011 14:35 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

Самое простое поробывать окрыть файл в иксклюзивном доступе с помощью функции API CreateFile, после этого пронанализировать ошибки с помощью функции GetLastError. http://msdn.microsoft.com/ru-ru/library/aa363874
Цитата:
An application also uses CreateFile to specify whether it wants to share the file for reading, writing, both, or neither. This is known as the sharing mode. An open file that is not shared (dwShareMode set to zero) cannot be opened again, either by the application that opened it or by another application, until its handle has been closed. This is also referred to as exclusive access.

When a process uses CreateFile to attempt to open a file that has already been opened in a sharing mode (dwShareMode set to a valid non-zero value), the system compares the requested access and sharing modes to those specified when the file was opened. If you specify an access or sharing mode that conflicts with the modes specified in the previous call, CreateFile fails.

Автор:  registration [ Чт фев 24, 2011 16:45 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

F-MAP писал(а):
Цитата:
Возможно один из вариантов, пробовать переименовать или переместить файл в цикле функцией (spf4.20)
Код:
WINAPI: MoveFileA KERNEL32.DLL
: RENAME-FILE ( from-a1 u1 to-a2 u2 -- ior)
DROP NIP SWAP MoveFileA ERR ;

ior - подскажет, если не ноль, что то не так, вроде 5 или 12 занят другим процессом


Спасибо, F-MAP за совет, есть информация к размышлению. Буду разбираться с кодом.
Правда в переименовании настораживают такие моменты:
1. Нужно следить за новым именем файла, а файл не один а 2-3. То есть появляется список соответствия первоначальных и новых имен файла(ов)
2. если файл свободен, он без проблем переименовывается, а мне нужно первоначальное имя. Файлам придется возвращать первоначальное имя.

Но все равно еще раз спасибо за помощь и информацию

Автор:  registration [ Чт фев 24, 2011 16:56 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

Alexander писал(а):
Самое простое поробывать окрыть файл в иксклюзивном доступе с помощью функции API CreateFile, после этого пронанализировать ошибки с помощью функции GetLastError. http://msdn.microsoft.com/ru-ru/library/aa363874

Сасибо за совет, Alexander, пока точно не знаю, но нутром чувствую, что это как раз то что мне нужно. Я в программировании не силен, но интересуюсь, поэтому пошел по ссылке учить мат часть. Спасибо за ссылку, думаю именно с API мне и нужно работать.
Если что-то получиться, о результатах отпишусь.

Автор:  chess [ Чт фев 24, 2011 17:03 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

registration писал(а):
2. если файл свободен, он без проблем переименовывается, а мне нужно первоначальное имя. Файлам придется возвращать первоначальное имя.

Имя исходного (интересующего) файла при переименовании и выбирайте в качестве нового.

Автор:  Гость [ Чт фев 24, 2011 20:05 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

chess писал(а):
registration писал(а):
2. если файл свободен, он без проблем переименовывается, а мне нужно первоначальное имя. Файлам придется возвращать первоначальное имя.

Имя исходного (интересующего) файла при переименовании и выбирайте в качестве нового.

Сейчас попробовал в Файловых менеджерах такую операцию сделать (для теста) получил результат:
1. FAR: Error Cannot copy the file filename onto itself
2. Total Commander без проблем.
Сейчас в nnCron буду пробовать.

Спасибо, chess, за уточнение. Помогли сняться с ручника.

Автор:  registration [ Чт фев 24, 2011 20:19 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

Гость писал(а):
2. Total Commander без проблем.

вернее без видимых сообщений о проблемах.

Да, не думал что, Гостем тоже постить можно.

Автор:  AlikasS [ Пт фев 25, 2011 18:49 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

к nnCron-e можно делать так
Код:
: Ждем_доступности_файла { a u -- }
BEGIN
    200 PAUSE
    a u R/W OPEN-FILE SWAP CLOSE-FILE DROP 0=
UNTIL
;

Автор:  F-MAP [ Пт фев 25, 2011 19:39 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

Цитата:
к nnCron-e можно делать так...

Есть опасность зацикливания, если файл создан или открыт в SHARE MODE, но возможно не прав.

Автор:  AlikasS [ Пт фев 25, 2011 19:52 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

Цитата:
к nnCron-e можно делать так
Код:
R/W OPEN-FILE

а это точно не поможет?
а как захватить силами SPF монопольный доступ?

Автор:  F-MAP [ Пт фев 25, 2011 21:01 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

Цитата:
как захватить силами SPF монопольный доступ?

Может ошибаюсь, но похоже ни как, только доступом (обертками) к средствам ОС

Автор:  spf [ Сб фев 26, 2011 04:47 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

В SPForth слово OPEN-FILE открывает файл в экслюзивном доступе ("монопольном", в таком режим файл может открыть только один процесс, остальным будет ошибка 32). Переименовать тоже не получится.

Слово OPEN-FILE-SHARED -- открывает в разделяемом доступе (в таком режиме файл могут открыть несколько процессов). Файл, открытый этим словом, может быть переименован, перенесен, и даже удален (реально файл удалится после закрытия).

Может быть полезно следующее слово из комплекта Eserv/3
Код:
1000 VALUE vFileWatchPeriod \ период проверки

: WAIT-FILE-EXCLUSIVE ( c-addr u  tout -- ior )
  \ ожидание монопольного доступа к файлу
  \ tout -- таймут ожидания в ms, если -1 то вечное ожидание
  \ если дождались, ior = 0
  \ если timeout, ior = -1
  { a u tout }
  a u FILE-EXIST 0= IF 2 EXIT THEN
  tout vFileWatchPeriod UMAX TO tout
  BEGIN
    a u R/O OPEN-FILE 0=     IF
    CLOSE-FILE THROW 0 EXIT  THEN DROP
    vFileWatchPeriod PAUSE
    tout -1 <> IF
      tout vFileWatchPeriod U< IF -1 EXIT THEN
      tout vFileWatchPeriod - TO tout
    THEN
  AGAIN
;

Это слово не подходит для конкурентного захвата файла (когда несколько процессов ждут один файл), т.к. оно "не захватывает" файл, он остается свободным и может быть захвачен другим процессом.

Автор:  F-MAP [ Вс фев 27, 2011 12:13 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

Цитата:
Файл формируеся на разделяемом сетевом ресурсе, произвольной машиной в сети

Если файл формирует не "левая" программа, может заставить ее подать сигнальчик в нужное время нужному процессу (DDE, COM, и тп)

Автор:  registration [ Ср мар 09, 2011 12:59 ]
Заголовок сообщения:  Re: Как определить что "файл занят другим процессом"?

Написал такой код:
Код:
#( File_Busy_Test2
AsLoggedUser
\ NoActive
SingleInstance
WatchFile: "C:\dir1\dir2\dir3\????abc.dbf"

Action:
FOR-FILES: "C:\dir1\dir2\dir3\????abc.dbf"
  BEGIN
    PAUSE: 200
    FOUND-FULLPATH R/W OPEN-FILE-SHARED
    GetLastError
    32 <> \ 32 -код ошибки ERROR_SHARING_VIOLATION
  UNTIL
CLOSE-FILE DROP
\ ." Закрыли файл" CR
." Всё вышли из цикла UNTIL" CR
;FOR-FILES
." Всё вышли из цикла FOR-FILES" CR
)#

Код вроде отрабатывает, в консоли вижу вывод строк выхода из циклов,
но после этого возникает ошибка: 1772 File_Busy_Test2: Ошибка стека в Action:
и файл держится уже кроном (возможно не срабатывает CLOSE-FILE DROP)
Подскажите в чём проблема со стеком?

Страница 1 из 2 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/