![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
как узнать открыт файл или нет?
umbra © (2005-09-21 12:17:00)Я подозреваю, что это довольно частый вопрос, но поиском ничего не нашел. Как при доступе к файлу определить открыт ли он уже каким либо процессом (приложением) или нет? Намекните, пожалуйста
Джо (2005-09-23 12:53:00) [21]
> [22] Tonich © (23.09.05 11:50)
1. CreateFile возвращает INVALID_HANDLE_VALUE не только в сабжевой ситуации (кстати, не вполне четко обрисованной). Причин может быть много, одна из них - у процесса может быть недостаточно прав на открытие файла, файл может быть зашифрован, да мало ли что?
2. Название функции не соответствует назначению :)
Tonich (2005-09-23 11:50:00) [22]
> Джо © (21.09.05 20:20) [10]
это один из вариантов , проверить используется ли файл други приложением или нет!!! или ВЫ считаете что нет???
ТоХда прошу научить как же надо это делать, а то от ВАС было только замечание ....
Игорь Шевченко (2005-09-23 01:07:00) [23]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 и ресурсы системы будут захвачены и не освобождены, что весьма плохо.
С уважением,
DiamondShark (2005-09-22 23:44:00) [24]
> ИМХО, 3-й вариант более логичный и более читабельный
А вариант
Win32Check( GetCommState(...) );
ещё читабельней.
Мексиканец (2005-09-22 21:41:00) [25]Удалено модератором
Мексиканец (2005-09-22 21:39:00) [26]Удалено модератором
Fay (2005-09-22 19:05:00) [27]2 simpson © (22.09.05 17:16) [16]
Полностью согласен. Но, недеюсь, Вы не станете утверждать, что в примере [1] ожидается некая невдолбенно исключительная ситуация 8)
simpson (2005-09-22 17:16:00) [28]> Fay © (22.09.05 16:33) [15]
Про необходимость. Позволю не согласиться и попробую раскрыть тему :)
Вариант не ленивый. Он прежде всего логичный.
Если исключить программы, которые "истинные пацаны" пишут "чиста на АПИ", то получается, половина проекта, использующая VCL, написана со вcесторонним использованием SEH (как минимум, потому что используется VCL :) ), а другая половина? Использует конструкции типа 1 и 2?
Мне не лень написать кучу if'ов. Мне лень обладать механизмом обработки исключений и не пользоваться им - он специальнодля этого придуман. А еще лень иметь в одном проекте две принципиально разные схемы действий при возникновении исключительных ситуаций.
Про читабельность - согласен, это - субъективное.
> З.Ы.
> причастные 8)
Извиняюсь, быстро писАл. :)
Просто задолбали ученики церковно-приходских школ, которые почему-то решили пойти в программисты, не выучив родной язык.
Fay (2005-09-22 16:33:00) [29]2 simpson © (22.09.05 10:55) [14]
>> ИМХО, 3-й вариант более логичный и более читабельный
Он более ленивый (хотя я и сам так часто пишу). Тема небходимости try..finally не раскрыта.
>> "Извените" пишется через "и",
Согласен, но у многих это (через "е") уже в крови 8).
З.Ы.
прича стные 8)
simpson (2005-09-22 10:55:00) [30]> Мексиканец © (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.
ЗЫ: "Извените" пишется через "и", а причатсные обороты в таком случае нужно отделять запятой: "Достаточно проверять значения, возвращаемые функциями".
Такое впечатление, что русский язык изучался по китайскому букварю.
Джо (2005-09-22 01:27:00) [31]
> [12] Мексиканец © (22.09.05 00:11)
Вызываем
WritePrivateProfileString('','','','d:\1.ini');на XP
начинаем думать :))
Мексиканец (2005-09-22 00:11:00) [32]Извените конечно, но я что то не припомню случая когда вызовы API функций нужно контролировать блоками try...finally. API функции не могут вызвать исключительную ситуацию. Достаточно проверять значения возвращаемые функциями и если ошибка (как правило 0) то получить расшириный код ошибки функцией GetLastError().
Сказанное не относится к манипуляциям с возвращаемыми значениями функций :)
Мексиканец (2005-09-22 00:01:00) [33]Вообще смысл в том, что те приложения, для которых, запись в файл с которым они работают, во время работы критично, должны выставлять атрибут только для чтения либо запрещать вовсе. Программа которая обращается к файлу не получает доступа на запись, так как открывшая файл программа запретила его. Так что если разработчик придерживался этой концепции, то нужно просто проверять причину ошибки открытия файла функцией GetLastError().
Примерно это выглядит так:
hFile:= CreateFile();
if hFile = 0 then
case GetLastError() of
...
end;
Джо (2005-09-21 20:20:00) [34]
> [9] Tonich © (21.09.05 20:13)
А ты разве сказал человеку, как узнать, открыт или закрыт файл? :)
Tonich (2005-09-21 20:13:00) [35]Удалено модератором
Джо (2005-09-21 18:09:00) [36]
>
> [7] Eraser © (21.09.05 17:02)
>для API вызовов защищёные блоки никчему.
Бывает, что и "к чему", но в данном случае - уж точно ни к чему ;)
Eraser (2005-09-21 17:02:00) [37]
> Tonich © (21.09.05 12:20) [1]
Согласен с [4] и [6], для API вызовов защищёные блоки никчему.
Джо (2005-09-21 16:33:00) [38]
>
> [5] Tonich © (21.09.05 14:53)
>
> > Fay © (21.09.05 14:41) [4]
>
> дань привычке )))
> Только я вас умоляю, давайте не будим развивать тему
> скорости выполнения и ресурсозатрат кода
А причем тут затраты и прочее? Блок finally-то пустой ;)
Tonich (2005-09-21 14:53:00) [39]
> Fay © (21.09.05 14:41) [4]
дань привычке )))
Только я вас умоляю, давайте не будим развивать тему
скорости выполнения и ресурсозатрат кода
Fay (2005-09-21 14:41:00) [40]2 Tonich © (21.09.05 12:20) [1]
Зачем try..finally ?