Forth
http://fforum.winglion.ru/

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

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

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

GetLastError ненужен.

Код:
\ ...
  R/W OPEN-FILE-SHARED ( h|0   0|ior )
  DUP IF  NIP 32 <>   ELSE   DROP CLOSE-FILE THROW TRUE  THEN
UNTIL
  \ файл уже закрыт, если был открыт.

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

Может, на стеке муча кусора остается после отработки циклов?

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

WingLion писал(а):
Может, на стеке муча кусора остается после отработки циклов?
Вполне возможно, только как проверить?
Код любезно предоставленный Гостем вроде рабочий,ошибка не возникает (????), только непопонятно многое.

Написал стековую нотацию для кода, чтоб понять происходящее на стеке
Есть такие вопросы
1. для чего дублировать ior на вершине стека, если потом одну копию его удаляем?
2. Непонятно как выполняется CLOSE-FILE при таком состоянии стека на момент
исполнения?
Код:
FOUND-FULLPATH R/W OPEN-FILE-SHARED (  --> fileid ior )
  DUP ( fileid ior --> fileid ior ior )
  \ Вопрос: для чего дублировать ior?
IF ( --> )( fileid ior ior --> fileid ior ior )
  \ если ior <> 0
   \ Вопрос: Если далее мы ior удаляем?
  NIP ( fileid ior ior --> fileid ior )
  32 ( fileid ior --> fileid ior 32 )
  <> ( fileid ior 32 --> fileid flag )
ELSE ( --> )( fileid 0 0 --> fileid 0 0 )
  \ если ior OPEN-FILE-SHARED = 0
  \ т.е. файл нормально открылся
  DROP ( fileid 0 0 --> fileid 0 )
  \ А ниже мне непонятно, для CLOSE-FILE
  \ на стеке должно быть ( fileid -->
  \ а у нас ( fileid 0 -->
  CLOSE-FILE ( fileid 0 --> ???? )
  \ дальше я стек отследить не смог
  THROW
  TRUE
THEN

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

registration писал(а):
DUP ( fileid ior --> fileid ior ior )
\ Вопрос: для чего дублировать ior?
IF ( --> )( fileid ior ior --> fileid ior ior )

тут ошибочка в стековой нотации. Дублируется ior как раз для IF , который поглащает флаг, т.е. нижняя строчка должна выглядеть так:
IF ( fileid ior ior --> fileid ior )
registration писал(а):
\ Вопрос: Если далее мы ior удаляем?
NIP ( fileid ior ior --> fileid ior )

нет, ошибка была выше, удаляется fid
registration писал(а):
32 ( fileid ior --> fileid ior 32 )
<> ( fileid ior 32 --> fileid flag )

соответственно не так, а:
<> ( ior 32 --> flag )
ну и так далее.
Одна из идей Форта в том, что входящие параметры ВСЕГДА ПОГЛОЩАЮТСЯ (хотя ему следуют не всегда).

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

Спасибо, mOleg, за потраченное на меня время. Исправил стековую нотацию. Возникли ещё вопросы.
1. Перед IF на стеке отсутствует результат операции сравнения ( flag ). В IF входим со значением ior оставшимся от OPEN-FILE-SHARED
Вопрос: это и будет, в данном случае, flag для IF?
2. Мне непонятно, что для THROW на стеке должно быть и что останется, на стеке когда THROW отработает?
3. Для чего вообще THROW в данном коде?
Код:
FOUND-FULLPATH R/W OPEN-FILE-SHARED (  --> fileid ior )
  DUP ( fileid ior --> fileid ior ior )
  \ перед IF на стеке отсутствует результат операции
  \ сравнения ( flag ). В IF входим со значением ior
  \ оставшимся от OPEN-FILE-SHARED
  \ Вопрос: это и будет, в данном случае, flag для IF?
IF ( fileid ior ior --> fileid ior )
  \ если ior <> 0
  NIP ( fileid ior --> ior )
  32 ( ior --> ior 32 )
  <> ( ior 32 --> flag )
ELSE ( fileid 0 0 --> fileid 0 )
  \ если ior OPEN-FILE-SHARED = 0
  \ т.е. файл нормально открылся
  DROP ( fileid 0 --> fileid )
  CLOSE-FILE ( fileid --> ior )
  \ А ниже мне непонятно, что для THROW
  \ на стеке должно быть и что останется,
  \ на стеке когда THROW отработает?
  THROW
  TRUE
THEN

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

registration писал(а):
1. Перед IF на стеке отсутствует результат операции сравнения ( flag ). В IF входим со значением ior оставшимся от OPEN-FILE-SHARED
Вопрос: это и будет, в данном случае, flag для IF?

да, в Форте IF реагирует на 0, либо на отличное от него значение, а флаги
TRUE = -1
FALSE = 0.
Т.е. не так как в Си или Паскале!!! Впрочем, я это уже описывал.

registration писал(а):
2. Мне непонятно, что для THROW на стеке должно быть и что останется, на стеке когда THROW отработает?

опять же уже было описано и CATCH и THROW
чуть позже продолжу

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

итак, по коду:
registration писал(а):
CLOSE-FILE ( fileid --> ior )
\ А ниже мне непонятно, что для THROW
\ на стеке должно быть и что останется,
\ на стеке когда THROW отработает?
THROW

THROW снимает с вершины стека число, если оно отлично от нуля, выполняется код, вызывающий исключение, если нуль - управление передается коду, расположеному за THROW.

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

Очень похожая ситуация. Пресловутый usb.wsf создан на сетевом диске одной из рабочих станций. Все WS обходить - долгая песня (хотя, видимо, придется). А работать мешает. Может есть возможность определить в чьем реестре он прописан?
Ответ, если можно, по E-mail: 696944.110@mail.ru
Заранее спасибо.
Алексей Кашкаров

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

Забыл добавить, что сеть Microsoft без домена

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

Если тема еще актуальна, то позвольте, как говорится, сказать:
registration писал(а):
Код:
    FOUND-FULLPATH R/W OPEN-FILE-SHARED
    GetLastError
    32 <> \ 32 -код ошибки ERROR_SHARING_VIOLATION
  UNTIL
CLOSE-FILE DROP


Здесь не совсем так. В документации крона вообще ничего не сказано о слове OPEN-FILE-SHARED. Но из приведенного там примера можно сделать вывод, что оно возвращает дескриптор файла (FID), открытого для немонопольного доступа. Там же этот дескрипттор присваивается переменной. А слово CLOSE-FILE используется соответствоенно с этим же дескриптором (или fileID). Т.е. не хватает переменной для дискриптора, открывающего и закрывающего файл. (отсюда, видимо, и проблема стека, т.к. слово возвращает дискриптор)
В кроне так:
Код:
S" test.txt" R/O OPEN-FILE-SHARED THROW list-file !   \ заносим ID файла в переменную, чтобы иметь возможность с ним работать для записи, чтения и пр.
Далее
list-file @ CLOSE-FILE DROP    \ закрываем файл по его ID

Вот. Ну и еще несколько замечаний:
Если открывать файл словом OPEN-FILE-SHARED, то каким образом мы увидим, что он занят? Т.е. он может быть занят занят процессом, но не монопольно, т.е. мы не поймем, можно ли его перемещать собственно? Вот если его открыть словом OPEN-FILE (т.е. использовать монопольный доступ), то, отловив ошибку, поймем, что файл уже занят. И, поняв, что он занят, сделаем паузу, проверим еще раз и т.д. пока не освободится.
Ну вот как то так, как я думаю.
Но и это решение выглядит как то костыляво. Вот если через winAPI как-нибудь... Но эта тема для меня темный лес. Однако такая простенькая прога Unlocker показывает все процессы, которые работают с файлом и даже может их легко разблокировать. Не знаю, сделано ли в ней средствами системы или как то другим способом.

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

Сергей_К писал(а):
Но и это решение выглядит как то костыляво. Вот если через winAPI как-нибудь...

Открыть файл на запись и есть самый простой способ узнать, открыт ли файл на запись другим процессом или нет. Если ошибка - либо файл не существует либо уже открыт на запись. Можно конечно через недокументированные функции добраться до списка хэндлов всех открытых файлов и искать там нужный файл - но это уже будет не так тривиально и просто.

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