Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.01.15;
Скачать: CL | DM;

Вниз

TFileStream   Найти похожие ветки 

 
Очень Злой   (2011-10-03 16:04) [0]

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

fmOpenWrite или fmOpenWrite or fmCreate

И если файл существует, то нужно ли вручную передвигать позицию или она сама встанет в конец файла?


 
Anatoly Podgoretsky ©   (2011-10-03 16:15) [1]

Раз, хочешь создать, то естественно надо fmCreate


 
Очень Злой   (2011-10-03 16:36) [2]

если делаю так:
procedure TFrmMain.Button4Click(Sender: TObject);
var
s:string;
begin
s:="Тра-та-та";
with TFileStream.Create("s.txt", fmOpenWrite) do
try
  Seek(0,soFromEnd);
  WriteBuffer(s[1],length(s));
finally
  free;
end;
end;


То к существующим файлам все нормально добавляется, но если файла нет, то получаем эксепшн.

А если так:
procedure TFrmMain.Button4Click(Sender: TObject);
var
s:string;
begin
s:="Тра-та-та";
with TFileStream.Create("s.txt", fmCreate or fmOpenWrite) do
try
  Seek(0,soFromEnd);
  WriteBuffer(s[1],length(s));
finally
  free;
end;

end;

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


 
Ega23 ©   (2011-10-03 16:36) [3]


> Нужно добавить данные в конец файла, если файла нет - то
> создать его.


with TMemoryStream.Create do
 try
   if FileExists(aFileName) then
   begin
     LoadFromFile(aFileName);
     Position := Size;
   end;
   WriteBuffer(.....);
   SaveToFile(aFileName);
 finally
   Free;
 end;


 
Очень Злой   (2011-10-03 16:49) [4]


> if FileExists(aFileName) then


Т.е. предлагаете сначала вручную проверить наличие файла?

Просто я думал что TFileStream сам может определить что файла нет и создать его...


 
Ega23 ©   (2011-10-03 16:54) [5]


> Просто я думал что 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;


 
Dennis I. Komarov ©   (2011-10-03 17:11) [6]


> Ega23 ©   (03.10.11 16:36) [3]

А если файл не мелкий, и дергать надо не редко?


 
Ega23 ©   (2011-10-03 17:17) [7]


> А если файл не мелкий, и дергать надо не редко?


ну можно так:

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;


 
Медвежонок Пятачок ©   (2011-10-03 17:24) [8]

> Просто я думал что TFileStream сам может определить что
> файла нет и создать его...

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


 
Очень Злой   (2011-10-03 17:35) [9]


> ну можно так:


В принципе почти так и сделал уже:

...
// Если юзер в оффлайне - кидаем все в файл, чтобы выдать когда появится в онлайне
 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;
...


 
Dennis I. Komarov ©   (2011-10-03 17:43) [10]


> // Если юзер в оффлайне - кидаем все в файл, чтобы выдать
> когда появится в онлайне
>

Если сервак еще не знает что клиент отвалился, то...

З.Ы. Удалять, после получения квитанции о доставке


 
Очень Злой   (2011-10-03 18:04) [11]


> Если сервак еще не знает что клиент отвалился, то...
>
> З.Ы. Удалять, после получения квитанции о доставке


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


 
DVM ©   (2011-10-03 18:27) [12]


>   if FileExists(filename)

Это потенциальные грабли. В момент вызова FileExists файл был (или не было его), но спустя доли секунды до вызова TFileStream.Create другой поток/процесс его создал (удалил). Надо обращаться сразу к нужным функциям создания/удаления файла и обрабатывать ошибки/исключения, а не загромождать код проверками.


 
Очень Злой   (2011-10-03 19:04) [13]


>
> Это потенциальные грабли. В момент вызова FileExists файл
> был (или не было его), но спустя доли секунды до вызова
> TFileStream.Create другой поток/процесс его создал (удалил).
>  Надо обращаться сразу к нужным функциям создания/удаления
> файла и обрабатывать ошибки/исключения, а не загромождать
> код проверками.


Угу. Но приложение однопоточное... А другие процессы не должны интересоваться этими файлами...


 
Игорь Шевченко ©   (2011-10-03 21:11) [14]


> Надо обращаться сразу к нужным функциям создания/удаления
> файла и обрабатывать ошибки/исключения


Найди 10 отличий между проверкой и созданием или вызовом, обломом и последующим созданием


 
Palladin ©   (2011-10-03 22:07) [15]

кто на ком стоял?


 
Очень Злой   (2011-10-03 23:03) [16]


>
> Это потенциальные грабли. В момент вызова FileExists файл
> был (или не было его), но спустя доли секунды до вызова
> TFileStream.Create другой поток/процесс его создал (удалил).
>  Надо обращаться сразу к нужным функциям создания/удаления
> файла и обрабатывать ошибки/исключения, а не загромождать
> код проверками.


Ну если бы было более 1 потока, в которых возможно обращение к файлу, то наверное можно было бы обойтись критическими секциями.
В данном случае приложение однопоточное, то есть, приложние не должно "бояться" само себя. В алгоритме не предусмотрена работа других процессов с этими файлами. Ну конечно никто не застрахован от разных случаев (Например Вася Пупкин может зайти и с помощью какого-нить приложения (допустим файлового менеджера) открыть\изменить\удалить файл и это может произойти в не самый благоприятный момент (допустим между теми же вызовами FileExists и TFileStream.Create). Но это ведь уже не штатный режим работы создаваемого приложения. Конечно, могу ошибаться, но что-то мне кажется что от таких вещей нет смысла защищаться, ибо от всевозможных внешний воздействий никогда полностью нельзя защититься.


 
Dennis I. Komarov ©   (2011-10-04 12:37) [17]


> В алгоритме не предусмотрена работа других процессов с этими
> файлами.

Ты это каждому антивирусу говорить будешь...


 
DVM ©   (2011-10-04 15:42) [18]


> Очень Злой   (03.10.11 19:04) [13]


> Угу. Но приложение однопоточное... А другие процессы не
> должны интересоваться этими файлами...

Должны - не должны, что работа программы будет зависеть от расположения звезд на небосводе?
А вот им антивирус заинтересуется и залочит намертво.


> Игорь Шевченко ©   (03.10.11 21:11) [14]


> Найди 10 отличий между проверкой и созданием или вызовом,
>  обломом и последующим созданием

Сам разницу не видишь?

Проверка, кстати, может и не показать наличия файла, в старых версиях Delphi FileExists может неправильно себя вести в новых версиях Win. В новых Delphi эта функция стала более интеллектуальной.

Потом, зачем постоянно проверять? Зачем захламлять код if..then..else, когда можно сделать централизованную обработку исключений. Давай проверять все тогда уж, чего мелочиться то?


 
DVM ©   (2011-10-04 15:46) [19]


> Очень Злой   (03.10.11 23:03) [16]


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

От всех возможных ошибок можно защититься не городя свои бестолковые проверки, а доверившись WinApi. Будет ошибка - будет исключение.

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


 
makvell   (2011-10-04 16:23) [20]


> DVM ©   (03.10.11 18:27) [12]
>
>  Надо обращаться сразу к нужным функциям создания/удаления
> файла и обрабатывать ошибки/исключения, а не загромождать
> код проверками.


Я, как-то, всегда считал, что логика на исключениях - плохо, и, нужно поискать проблему в другом месте :)


 
DVM ©   (2011-10-04 16:46) [21]


> makvell   (04.10.11 16:23) [20]


> Я, как-то, всегда считал, что логика на исключениях - плохо,
>  и, нужно поискать проблему в другом месте :)

Это не логика, это обработка ошибок. Логика - это когда создают специально свои типы исключений и генерируют их в ситуациях, где нет ошибок, а есть  штатные варианты поведения программы.


 
Игорь Шевченко ©   (2011-10-04 17:30) [22]

DVM ©   (04.10.11 15:42) [18]

Я к другому - я к тому, что между моментом исключения и моментом вызова функции ситуация может точно также изменится, как между проверкой и вызовом функции


 
DVM ©   (2011-10-04 18:02) [23]


> Игорь Шевченко ©   (04.10.11 17:30) [22]


> Я к другому - я к тому, что между моментом исключения и
> моментом вызова функции ситуация может точно также изменится

Согласен. В данном конкретном случае бессмысленность вызова FileExists не очень наглядна, но есть другие случаи.


 
Дмитрий Белькевич   (2011-10-05 12:41) [24]


> Я, как-то, всегда считал, что логика на исключениях - плохо


И логика на исключениях - хорошо, если писать ровно. И проверка лишняя - нужно возвращаемое исключение обрабатывать:

1.Ты никогда не знаешь, кому файл может еще понадобится.
2. Приложение сегодня - однопоточное, завтра - многопоточное. Кто знает? Полезут баги - будешь говорить, что потоки - плохо.



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

Текущий архив: 2012.01.15;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.01 c
15-1316688403
boriskb
2011-09-22 14:46
2012.01.15
Деньжат конечно маловато, но и работа не трудная


15-1317155402
Юрий
2011-09-28 00:30
2012.01.15
С днем рождения ! 28 сентября 2011 среда


2-1317892848
ford
2011-10-06 13:20
2012.01.15
findfirst не ищет в temp пользователя win7


9-1175164239
crytogen
2007-03-29 14:30
2012.01.15
нарисовать трубу в OpenGL по точкам


15-1317426033
Кто б сомневался
2011-10-01 03:40
2012.01.15
Замедленный скролл при включенном видео в Win 7