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

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.003 c
3-1269712883
dik59
2010-03-27 21:01
2012.01.15
Очередные загадки Firebird 2


15-1314770110
Омлет
2011-08-31 09:55
2012.01.15
RSS для DelphiMaster


15-1316959585
Pit
2011-09-25 18:06
2012.01.15
Несколько вопросов по Android


15-1317303611
БарЛог
2011-09-29 17:40
2012.01.15
Контроллеры домена для разных сайтов


15-1317241802
Юрий
2011-09-29 00:30
2012.01.15
С днем рождения ! 29 сентября 2011 четверг





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский