![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TFileStream [D7, XP]
Очень Злой © (2011-10-03 16:04:00)Нужно добавить данные в конец файла, если файла нет - то создать его.
Вопрос в том, какой режим открытия нужно использовать?
fmOpenWrite или fmOpenWrite or fmCreate
И если файл существует, то нужно ли вручную передвигать позицию или она сама встанет в конец файла?
Дмитрий Белькевич (2011-10-05 12:41:00) [1]
> Я, как-то, всегда считал, что логика на исключениях - плохо
И логика на исключениях - хорошо, если писать ровно. И проверка лишняя - нужно возвращаемое исключение обрабатывать:
1.Ты никогда не знаешь, кому файл может еще понадобится.
2. Приложение сегодня - однопоточное, завтра - многопоточное. Кто знает? Полезут баги - будешь говорить, что потоки - плохо.
DVM (2011-10-04 18:02:00) [2]
> Игорь Шевченко © (04.10.11 17:30) [22]
> Я к другому - я к тому, что между моментом исключения и
> моментом вызова функции ситуация может точно также изменится
Согласен. В данном конкретном случае бессмысленность вызова FileExists не очень наглядна, но есть другие случаи.
Игорь Шевченко (2011-10-04 17:30:00) [3]DVM © (04.10.11 15:42) [18]
Я к другому - я к тому, что между моментом исключения и моментом вызова функции ситуация может точно также изменится, как между проверкой и вызовом функции
DVM (2011-10-04 16:46:00) [4]
> makvell (04.10.11 16:23) [20]
> Я, как-то, всегда считал, что логика на исключениях - плохо,
> и, нужно поискать проблему в другом месте :)
Это не логика, это обработка ошибок. Логика - это когда создают специально свои типы исключений и генерируют их в ситуациях, где нет ошибок, а есть штатные варианты поведения программы.
makvell (2011-10-04 16:23:00) [5]
> DVM © (03.10.11 18:27) [12]
>
> Надо обращаться сразу к нужным функциям создания/удаления
> файла и обрабатывать ошибки/исключения, а не загромождать
> код проверками.
Я, как-то, всегда считал, что логика на исключениях - плохо, и, нужно поискать проблему в другом месте :)
DVM (2011-10-04 15:46:00) [6]
> Очень Злой (03.10.11 23:03) [16]
> Конечно, могу ошибаться, но что-то мне кажется что от таких
> вещей нет смысла защищаться, ибо от всевозможных внешний
> воздействий никогда полностью нельзя защититься.
От всех возможных ошибок можно защититься не городя свои бестолковые проверки, а доверившись WinApi. Будет ошибка - будет исключение.
Такие проверки имеют смысл только тогда, когда идет взаимодействие с пользователем, типа вопрос ему выдать перезаписать файл или нет, но полагаться на них не стоит.
DVM (2011-10-04 15:42:00) [7]
> Очень Злой (03.10.11 19:04) [13]
> Угу. Но приложение однопоточное... А другие процессы не
> должны интересоваться этими файлами...
Должны - не должны, что работа программы будет зависеть от расположения звезд на небосводе?
А вот им антивирус заинтересуется и залочит намертво.
> Игорь Шевченко © (03.10.11 21:11) [14]
> Найди 10 отличий между проверкой и созданием или вызовом,
> обломом и последующим созданием
Сам разницу не видишь?
Проверка, кстати, может и не показать наличия файла, в старых версиях Delphi FileExists может неправильно себя вести в новых версиях Win. В новых Delphi эта функция стала более интеллектуальной.
Потом, зачем постоянно проверять? Зачем захламлять код if..then..else, когда можно сделать централизованную обработку исключений. Давай проверять все тогда уж, чего мелочиться то?
Dennis I. Komarov (2011-10-04 12:37:00) [8]
> В алгоритме не предусмотрена работа других процессов с этими
> файлами.
Ты это каждому антивирусу говорить будешь...
Очень Злой (2011-10-03 23:03:00) [9]
>
> Это потенциальные грабли. В момент вызова FileExists файл
> был (или не было его), но спустя доли секунды до вызова
> TFileStream.Create другой поток/процесс его создал (удалил).
> Надо обращаться сразу к нужным функциям создания/удаления
> файла и обрабатывать ошибки/исключения, а не загромождать
> код проверками.
Ну если бы было более 1 потока, в которых возможно обращение к файлу, то наверное можно было бы обойтись критическими секциями.
В данном случае приложение однопоточное, то есть, приложние не должно "бояться" само себя. В алгоритме не предусмотрена работа других процессов с этими файлами. Ну конечно никто не застрахован от разных случаев (Например Вася Пупкин может зайти и с помощью какого-нить приложения (допустим файлового менеджера) открыть\изменить\удалить файл и это может произойти в не самый благоприятный момент (допустим между теми же вызовами FileExists и TFileStream.Create). Но это ведь уже не штатный режим работы создаваемого приложения. Конечно, могу ошибаться, но что-то мне кажется что от таких вещей нет смысла защищаться, ибо от всевозможных внешний воздействий никогда полностью нельзя защититься.
Palladin (2011-10-03 22:07:00) [10]кто на ком стоял?
Игорь Шевченко (2011-10-03 21:11:00) [11]
> Надо обращаться сразу к нужным функциям создания/удаления
> файла и обрабатывать ошибки/исключения
Найди 10 отличий между проверкой и созданием или вызовом, обломом и последующим созданием
Очень Злой (2011-10-03 19:04:00) [12]
>
> Это потенциальные грабли. В момент вызова FileExists файл
> был (или не было его), но спустя доли секунды до вызова
> TFileStream.Create другой поток/процесс его создал (удалил).
> Надо обращаться сразу к нужным функциям создания/удаления
> файла и обрабатывать ошибки/исключения, а не загромождать
> код проверками.
Угу. Но приложение однопоточное... А другие процессы не должны интересоваться этими файлами...
DVM (2011-10-03 18:27:00) [13]
> if FileExists(filename)
Это потенциальные грабли. В момент вызова FileExists файл был (или не было его), но спустя доли секунды до вызова TFileStream.Create другой поток/процесс его создал (удалил). Надо обращаться сразу к нужным функциям создания/удаления файла и обрабатывать ошибки/исключения, а не загромождать код проверками.
Очень Злой (2011-10-03 18:04:00) [14]
> Если сервак еще не знает что клиент отвалился, то...
>
> З.Ы. Удалять, после получения квитанции о доставке
Угу. думал над этим, но пока решил отложить до момента когда остальное заработает...но для начала хочу запустить отя бы это. А то ведь это пока еще клиентскую часть почти не писал... А при тестировании как всегда багов куча найдется, которые исправлять нужно будет...
Обычно, если что-то пишу - по ходу написания на недописанное ставлю заглушки и тестирую... А когда оно работает - то дописываю далее уже с приподнятым настроением... А тут хз сколько кода написал уже, но почти ничего и не протестировал...
Dennis I. Komarov (2011-10-03 17:43:00) [15]
> // Если юзер в оффлайне - кидаем все в файл, чтобы выдать
> когда появится в онлайне
>
Если сервак еще не знает что клиент отвалился, то...
З.Ы. Удалять, после получения квитанции о доставке
Очень Злой (2011-10-03 17:35:00) [16]
> ну можно так:
В принципе почти так и сделал уже:
...
// Если юзер в оффлайне - кидаем все в файл, чтобы выдать когда появится в онлайне
if not Online then
begin
filename:=inttostr(Header.contact)+'.ofm'; // Имя файла для хранения оффлайн-сообщений
if FileExists(filename)
then Mode:=fmOpenWrite
else Mode:=fmCreate or fmOpenWrite;
with TFileStream.Create(filename,Mode) do
try
Seek(0,soFromEnd);
WriteBuffer(SendHeader,sizeof(SendHeader)); //пишем заголовок посылки
WriteBuffer(Buf,SendHeader.operlen); //пишем тело посылки
finally
Free;
end;
end;
...
Медвежонок Пятачок (2011-10-03 17:24:00) [17]> Просто я думал что TFileStream сам может определить что
> файла нет и создать его...
а если файл есть и файл нужный, но сегодня четверг и луна в козероге, то перезаписать его
Ega23 (2011-10-03 17:17:00) [18]
> А если файл не мелкий, и дергать надо не редко?
ну можно так:
var
aMode: Word;
begin
if FileExists(aFileName) then
aMode := fmOpenRead or fmShareDenyNone
else
aMode := fmCreate;
with TFileStream.Create(aFileName, aMode) do
try
Position := Size;
WriteBuffer(....);
finally
Free;
end;
end;
Dennis I. Komarov (2011-10-03 17:11:00) [19]
> Ega23 © (03.10.11 16:36) [3]
А если файл не мелкий, и дергать надо не редко?
Ega23 (2011-10-03 16:54:00) [20]
> Просто я думал что TFileStream сам может определить что
> файла нет и создать его...
constructor TFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal);
var
LShareMode: Word;
begin
if (Mode and fmCreate = fmCreate) then
begin
LShareMode := Mode and $FF;
if LShareMode = $FF then
LShareMode := fmShareExclusive; // For compat in case $FFFF passed as Mode
inherited Create(FileCreate(AFileName, LShareMode, Rights));
if FHandle = INVALID_HANDLE_VALUE then
raise EFCreateError.CreateResFmt(@SFCreateErrorEx, [ExpandFileName(AFileName), SysErrorMessage(GetLastError)]);
end
else
begin
inherited Create(FileOpen(AFileName, Mode));
if FHandle = INVALID_HANDLE_VALUE then
raise EFOpenError.CreateResFmt(@SFOpenErrorEx, [ExpandFileName(AFileName), SysErrorMessage(GetLastError)]);
end;
FFileName := AFileName;
end;