Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];

Вниз

как узнать открыт файл или нет?   Найти похожие ветки 

 
umbra ©   (2005-09-21 12:17) [0]

Я подозреваю, что это довольно частый вопрос, но поиском ничего не нашел. Как при доступе к файлу определить открыт ли он уже каким либо процессом (приложением) или нет? Намекните, пожалуйста


 
Tonich ©   (2005-09-21 12:20) [1]

один из вариантов



function UseFile(FilePath:string):boolean;
var
HFileRes:HFILE;
begin

 Result := False;
 try
   if not FileExists(FilePath) then Exit;

   HFileRes := CreateFile(Pchar(FilePath),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,0);

   Result  := (HFileRes = INVALID_HANDLE_VALUE);
   if not Result then CloseHandle(HFileRes)
 finally
 end;



 
Digitman ©   (2005-09-21 12:21) [2]


>  Как при доступе к файлу


смотря что подразумевается под "доступ к файлу" ..


 
umbra ©   (2005-09-21 13:53) [3]


> Tonich ©


Спасибо!


 
Fay ©   (2005-09-21 14:41) [4]

2 Tonich ©   (21.09.05 12:20) [1]
Зачем try..finally ?


 
Tonich ©   (2005-09-21 14:53) [5]


> Fay ©   (21.09.05 14:41) [4]

дань привычке )))
Только я вас умоляю, давайте не будим развивать тему
скорости выполнения и ресурсозатрат кода


 
Джо ©   (2005-09-21 16:33) [6]


>
>  [5] Tonich ©   (21.09.05 14:53)
>
> > Fay ©   (21.09.05 14:41) [4]
>
> дань привычке )))
> Только я вас умоляю, давайте не будим развивать тему
> скорости выполнения и ресурсозатрат кода

А причем тут затраты и прочее? Блок finally-то пустой ;)


 
Eraser ©   (2005-09-21 17:02) [7]


> Tonich ©   (21.09.05 12:20) [1]

Согласен с [4] и [6], для API вызовов защищёные блоки никчему.


 
Джо ©   (2005-09-21 18:09) [8]


>
>  [7] Eraser ©   (21.09.05 17:02)
>для API вызовов защищёные блоки никчему.

Бывает, что и "к чему", но в данном случае - уж точно ни к чему ;)


 
Tonich ©   (2005-09-21 20:13) [9]

Удалено модератором


 
Джо ©   (2005-09-21 20:20) [10]


>  [9] Tonich ©   (21.09.05 20:13)

А ты разве сказал человеку, как узнать, открыт или закрыт файл? :)


 
Мексиканец ©   (2005-09-22 00:01) [11]

Вообще смысл в том, что те приложения, для которых, запись в файл с которым они работают, во время работы критично, должны выставлять атрибут только для чтения либо запрещать вовсе. Программа которая обращается к файлу не получает доступа на запись, так как открывшая файл программа запретила его. Так что если разработчик придерживался этой концепции, то нужно просто проверять причину ошибки открытия файла функцией GetLastError().
Примерно это выглядит так:
hFile:= CreateFile();
 if hFile = 0 then
   case GetLastError() of
    ...
   end;


 
Мексиканец ©   (2005-09-22 00:11) [12]

Извените конечно, но я что то не припомню случая когда вызовы API функций нужно контролировать блоками try...finally. API функции не могут вызвать исключительную ситуацию. Достаточно проверять значения возвращаемые функциями и если ошибка (как правило 0) то получить расшириный код ошибки функцией GetLastError().

Сказанное не относится к манипуляциям с возвращаемыми значениями функций :)


 
Джо ©   (2005-09-22 01:27) [13]


>  [12] Мексиканец ©   (22.09.05 00:11)

Вызываем
WritePrivateProfileString("","","","d:\1.ini"); на XP
начинаем думать :))


 
simpson ©   (2005-09-22 10:55) [14]

> Мексиканец ©   (22.09.05 00:11) [12]
> API функции не могут вызвать исключительную ситуацию

Орех?

> Достаточно проверять значения возвращаемые функциями

Рассмотрим простую ситуацию: открытие COM-порта, установка его параметров, таймаутов и т. д. Последовательный вызов нескольких API-функций.

Что лучше, конструкции вида:

hFile := CreateFile(...);
if hFile = INVALID_HANDLE_VALUE then
 begin
   Result := GetLastError;
   Exit;
 end;

if not GetCommState(...) then
 begin
   Result := GetLastError;
   Exit;
 end;

...


или


hFile := CreateFile(...);
if hFile <> INVALID_HANDLE_VALUE then
 begin
   if GetCommState(...) then
     begin
       ...
     end
   else
     Result := GetLastError;
 end
else
 Result := GetLastError;


либо

hFile := CreateFile(...);
if hFile = INVALID_HANDLE_VALUE then
 RaiseLastOSError;
try
 if not GetCommState(...) then
   RaiseLastOSError;
 ...

 if not SetCommState(...)  then
   RaiseLastOSError;
 ...
finally
 CloseHandle(hFile);
end;


ИМХО, 3-й вариант более логичный и более читабельный. Если есть механизм SEH, почему бы его не использовать? Тем более, он прекрасно поддреживается в Delphi.

ЗЫ: "Извените" пишется через "и", а причатсные обороты в таком случае нужно отделять запятой: "Достаточно проверять значения, возвращаемые функциями".
Такое впечатление, что русский язык изучался по китайскому букварю.


 
Fay ©   (2005-09-22 16:33) [15]

2 simpson ©   (22.09.05 10:55) [14]
>> ИМХО, 3-й вариант более логичный и более читабельный
Он более ленивый (хотя я и сам так часто пишу). Тема небходимости try..finally не раскрыта.

>> "Извените" пишется через "и",
Согласен, но у многих это (через "е") уже в крови 8).

З.Ы.
причастные 8)


 
simpson ©   (2005-09-22 17:16) [16]

> Fay ©   (22.09.05 16:33) [15]

Про необходимость. Позволю не согласиться и попробую раскрыть тему :)

Вариант не ленивый. Он прежде всего логичный.

Если исключить программы, которые "истинные пацаны" пишут "чиста на АПИ", то получается, половина проекта, использующая VCL, написана со вcесторонним использованием SEH (как минимум, потому что используется VCL :) ), а другая половина? Использует конструкции типа 1 и 2?

Мне не лень написать кучу if"ов. Мне лень обладать механизмом обработки исключений и не пользоваться им - он специально для этого придуман. А еще лень иметь в одном проекте две принципиально разные схемы действий при возникновении исключительных ситуаций.

Про читабельность - согласен, это - субъективное.

> З.Ы.
> причастные 8)

Извиняюсь, быстро писАл. :)
Просто задолбали ученики церковно-приходских школ, которые почему-то решили пойти в программисты, не выучив родной язык.


 
Fay ©   (2005-09-22 19:05) [17]

2 simpson ©   (22.09.05 17:16) [16]
Полностью согласен. Но, недеюсь, Вы не станете утверждать, что в примере [1] ожидается некая невдолбенно исключительная ситуация 8)


 
Мексиканец ©   (2005-09-22 21:39) [18]

Удалено модератором


 
Мексиканец ©   (2005-09-22 21:41) [19]

Удалено модератором


 
DiamondShark ©   (2005-09-22 23:44) [20]


> ИМХО, 3-й вариант более логичный и более читабельный

А вариант

Win32Check( GetCommState(...) );

ещё читабельней.


 
Игорь Шевченко ©   (2005-09-23 01:07) [21]

simpson ©   (22.09.05 17:16) [16]


> Мне не лень написать кучу if"ов. Мне лень обладать механизмом
> обработки исключений и не пользоваться им - он специально
> для этого придуман. А еще лень иметь в одном проекте две
> принципиально разные схемы действий при возникновении исключительных
> ситуаций.


Я целиком и полностью поддерживаю.

Лень, безусловно, дело благородное.
Она вынуждает писать код, подобный такому:

procedure TCanvas.Lock;
begin
 EnterCriticalSection(CounterLock);
 Inc(FLockCount);
 LeaveCriticalSection(CounterLock);
 EnterCriticalSection(FLock);
end;

function TCanvas.TryLock: Boolean;
begin
 EnterCriticalSection(CounterLock);
 try
   Result := FLockCount = 0;
   if Result then Lock;
 finally
   LeaveCriticalSection(CounterLock);
 end;
end;

То есть, в последнем примере между вызовами EnterCriticalSection и LeaveCriticalSection исключений на первый взгляд и не должно произойти.

Или такому:

procedure TFoo.Bar;
.....
   DC := GetDC(0);
   try
     for I:=Low(Boolean) to High(Boolean) do begin
       OldFont := SelectObject(DC, FCaptionFonts[I]);
       try
         GetTextMetrics(DC, tm);
         FCyCaptionFontChars[I] := tm.tmHeight;
       finally
         SelectObject(DC, OldFont);
       end;
     end;
   finally
     ReleaseDC(0, DC);
   end;
....
end;

Где тоже вроде исключений не может произойти.

Однако, исключения могут произойти в обоих случаях, если self=nil и ресурсы системы будут захвачены и не освобождены, что весьма плохо.

С уважением,


 
Tonich ©   (2005-09-23 11:50) [22]


> Джо ©   (21.09.05 20:20) [10]
это один из вариантов , проверить используется ли файл други приложением или нет!!! или ВЫ считаете что нет???
ТоХда прошу научить как же надо это делать, а то от ВАС было только замечание ....


 
Джо ©   (2005-09-23 12:53) [23]


>  [22] Tonich ©   (23.09.05 11:50)

1. CreateFile возвращает INVALID_HANDLE_VALUE не только в сабжевой ситуации (кстати, не вполне четко обрисованной). Причин может быть много, одна из них - у процесса может быть недостаточно прав на открытие файла, файл может быть зашифрован, да мало ли что?
2. Название функции не соответствует назначению :)


 
Джо ©   (2005-09-23 12:57) [24]


> ТоХда прошу научить как же надо это делать, а то от ВАС
> было только замечание ....

Не могу научить, ибо сам не знаю. Думаю даже, что это и почти невозможно сделать, т.е., определить "открыт ли файл каким-нибудь процессом". Осмелюсь даже предположить - что, в принципе, это и не имеет практической пользы, выяснять такие нюансы. Достаточно корректно обработать ситуацию, когда файл недоступен. А не выяснять, почему он недоступен.


 
Игорь Шевченко ©   (2005-09-23 13:21) [25]

Джо ©   (23.09.05 12:57) [24]

> Думаю даже, что это и почти невозможно сделать, т.е., определить
> "открыт ли файл каким-нибудь процессом".


Возможно. Но непросто.


 
Джо ©   (2005-09-23 13:38) [26]


>  [25] Игорь Шевченко ©   (23.09.05 13:21)
> Возможно. Но непросто.

Да я тоже думаю, что докопаться все-таки можно (конкретный способ назвать "сходу" не могу). А смысл? Только для каких-то системных утилит или в познавательных целях. "Познавательный смысл" в виду того, что просится готовое решение - исключается; системные утилиты - исключаю "интуитивно" (возможно, ошибаюсь).


 
Игорь Шевченко ©   (2005-09-23 13:57) [27]

Джо ©   (23.09.05 13:38) [26]


> А смысл? Только для каких-то системных утилит


Да, конечно. В прикладной софтине вроде ни к чему


 
umbra ©   (2005-09-23 14:34) [28]

пе
> обработать ситуацию, когда файл недоступен


А если он доступен, но чтобы решить, что делать дальше надо знать, открыт он или нет?


 
Джо ©   (2005-09-23 14:37) [29]


>  [28] umbra ©   (23.09.05 14:34)
> А если он доступен, но чтобы решить, что делать дальше надо
> знать, открыт он или нет?

Зависит, наверное, от того - что предполагается "делать". Это большая тайна?


 
simpson ©   (2005-09-23 14:41) [30]

> umbra ©   (23.09.05 14:34) [28]

Да нет таких прикладных задач, когда надо знать, открыт файл, или нет, прежде чем начинать с ним работу. Работа с файлами на прикладном уровне сводится к тому, чтобы попытаться открыть файл в нужном режиме, и, если это невозможно, выдать соответствующее сообщение об ошибке и отреагировать согласно условиям задачи (например, прекратить работу, или попытаться позже).

Ну узнал ты, что файл, к которому ты пытаешься обратиться, занят процессом "proga.exe". И что? Жестоко убьешь этот процесс, чтобы самому начать работу с занятым файлом? Не думаю. :)


 
umbra ©   (2005-09-23 14:43) [31]

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


 
simpson ©   (2005-09-23 14:45) [32]

> umbra ©   (23.09.05 14:43) [31]

Ну так причем же здесь сабж? Тебе всего лишь нужен механизм межпроцессного взаимодействия.


 
umbra ©   (2005-09-23 14:50) [33]

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


 
umbra ©   (2005-09-23 14:57) [34]


> что предполагается "делать"

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


 
Джо ©   (2005-09-23 15:09) [35]


>  [34] umbra ©   (23.09.05 14:57)
> Или например, при запуске проги надо убедиться, что это
> первый ее екземпляр. Для этого при запуске проверяется,
> открыт ли определенный файл -если открыт, то значит прога
> уже раз запущена, надо вторую закрывать. Опять таки, проще
> проверить файл, чем искать окна, процессы и т.д.

Очень показательный ответ.
Кстати, как думаешь - в какой место попадет твой замечательный лисапедный способ, если твою программу снимут из Task Manager"а? Или для этого предлагаешь решать задачу: "Как скрыть мой процесс из списка процессов"? Очень показательный ответ :(


 
umbra ©   (2005-09-23 15:23) [36]

аварийное завершение тоже можно перехватить и файл закрыть (удалить)
Но я согласен, пример не очень удачный. Хотя на этом замечательном лисапедном способе держится пол-линуха.


 
Игорь Шевченко ©   (2005-09-23 15:48) [37]


> Хотя на этом замечательном лисапедном способе держится пол-
> линуха.


Какая именно половина Linux"а ? :)


 
BiN ©   (2005-09-23 15:53) [38]

http://66.249.93.104/search?q=cache:B7JYEdq4hnMJ:delphimaster.ru/cgi-bin/forum.pl%3Fid%3D1121359278%26n%3D5+querydosdevi ce+%D0%BC%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B0+Delphi&hl=ru

а также

http://66.249.93.104/search?q=cache:mYb99Yo7iqwJ:www.delphimaster.ru/cgi-bin/forum.pl%3Fid%3D1120126541%26n%3D5+querydos device+%D0%BC%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B0+Delphi&hl=ru

(спасибо кэшу гугля)


 
umbra ©   (2005-09-23 16:00) [39]

Серверная, в основном. Самба, сендмейл, ксинетд, ссаш к примеру


 
ANB ©   (2005-09-23 17:05) [40]


> Или например, при запуске проги надо убедиться, что это
> первый ее екземпляр.
- это делается намного проще. А вот конкретный пример из реального проекта :
Есть консольная прога (текстовый режим, никаких окон), она время от времени отвечает на звонки по модему и складывает ответ в файл. Другая прога должна прочитать этот файл только, когда он не занят (в него не пишут). Повторное чтение неизмененного файла уже обработано и некритично. Вот таким способом и сделано - каждая из прог открывает файл в монопольном режиме и если не получается - ждет, пока получится. Хотя я бы сам, имхо, сделал бы по другому, но это самый тупорылый вариант, с учетом того, что из управляещей проги нет доступа к WinAPI.


 
Мексиканец ©   (2005-09-24 00:27) [41]

Не пойму чем не нравится такая конструкция?
hFile:= CreateFile();
if hFile = -1 then
 case GetLastError() of
 ...
 end;
Если можно объясните? Тем более что можно точно узнать причину по которой файл открыть не удалось. У меня, где-то была таблица значения возвращаемых значений, будет время, найду и кину сюда.


 
Мексиканец ©   (2005-09-24 00:47) [42]

umbra ©  (23.09.05 14:43) [31]

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

В виндовс каждая софтина для которой важно иметь монопольный доступ к файлу, должна выставить соответствующие атрибуты, тогда другая софтина просто не сможет прочитать файл пока та софтина не закончит с ним работу и не освободит его. Все просто. Не думаю что здесь есть почва для творчества.

>Или например, при запуске проги надо убедиться, что это первый ее
>екземпляр.

ИМХО строить решение данной задачи на файле, не стоит.


 
Fay ©   (2005-09-24 02:44) [43]

2 ANB ©   (23.09.05 17:05) [40]
>> с учетом того, что из управляещей проги нет доступа к WinAPI
Это как?!



Страницы: 1 2 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.013 c
14-1131453530
Priest
2005-11-08 15:38
2005.11.27
Подскажите интернет магазин


1-1131005206
Владислав
2005-11-03 11:06
2005.11.27
Автоматический вызов деструкторов при выходе из процедуры.


4-1127888849
Igi
2005-09-28 10:27
2005.11.27
Заблокировать клавиатуру


14-1131051081
Profi
2005-11-03 23:51
2005.11.27
Почему программисты на С++ ценятся больше чем на Delphi?


14-1130956736
Adil
2005-11-02 21:38
2005.11.27
Midlet na Java i problema s Nokia





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский