Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TFileStream [D7, XP]


Страницы:   1 2

Очень Злой ©   (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;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо