Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.10.2012, 09:01   #1
avd
Пользователь
 
Регистрация: 06.06.2010
Сообщений: 79
По умолчанию Не даёт покоя TFileStream и fmShareDenyNone.

У кого есть Delphi XE(2,3) перебилдите пожалуйста, хочется узнать вдруг у вас всё заработает. У меня 2010.

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  Stream: TFileStream;
  name: string;
  strl: tStringList;
begin
  strl := TStringList.Create();

  name := ExtractFileDir(Application.ExeName) + '\test.txt';

  Stream := TFileStream.Create(name, fmCreate or fmShareDenyNone);
  Stream.Write(AnsiString('123456789')[1], 9);

  strl.LoadFromFile(name); // У меня здесь исключение несмотря на fmShareDenyNone
  strl.Free;

  Stream.Free;

end;
avd вне форума Ответить с цитированием
Старый 16.10.2012, 11:02   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

проверил код у себя в Delphi 2006
та же фигня.

погуглил. Это широкоизвестный факт.
Насколько я понимаю, ключики с fmShareDenyxxxx Win API понимает только для режимов, когда файл открывается на чтение.
попробуйте, например
Stream := TFileStream.Create(name, fmOpenRead or fmShareDenyNone);

решение. каждый раз после записи в файл закрывайте поток.
вот так:
Код:

  if FileExists(name) then begin
    Stream := TFileStream.Create(name, fmOpenReadWrite);
    Stream.Seek(0, soFromEnd );
  end
  else
    Stream := TFileStream.Create(name, fmCreate);

  s := '123456789'#13#10;
  Stream.Write(s[1], Length(s));
  FreeAndNil(Stream);

Последний раз редактировалось Serge_Bliznykov; 16.10.2012 в 11:07.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 16.10.2012, 11:08   #3
astecenko
Homo Interneticus
Форумчанин
 
Аватар для astecenko
 
Регистрация: 04.03.2011
Сообщений: 611
По умолчанию

fmCreate = $FFFF - то бишь она перекрывает все с чем будет складываться (OR), и имеет эксклюзивный доступ.
По этому вначале создайте файл (с помощью CreateFile), а потом уже открывайте его файловым потоком с нужным Вам методом доступа.

Последний раз редактировалось astecenko; 16.10.2012 в 11:13.
astecenko вне форума Ответить с цитированием
Старый 16.10.2012, 11:32   #4
avd
Пользователь
 
Регистрация: 06.06.2010
Сообщений: 79
По умолчанию

Цитата:
каждый раз после записи в файл закрывайте поток.
Делать этого мне не хочется (хотя так и приходится делать) т. к. у меня пишется лог файл и теоретически за 1 сек. может возникать до 256 событий.
fmCreate в модуле Classes: fmCreate = $FF00;
Но, что интересно, блокнотом файл который
Код:
TFileStream.Create(name, fmCreate or fmShareDenyNone);
спокойно можно открыть!
Интересно всё-таки кто виноват в такой ситуации Delphi или API?

Можно конечно придумать что-то типа
Код:
  CopyFile(PWideChar(name), PWideChar(name + '0'), true);
  strl.LoadFromFile(name + '0');
  strl.Free;

Последний раз редактировалось avd; 16.10.2012 в 11:36.
avd вне форума Ответить с цитированием
Старый 16.10.2012, 11:39   #5
astecenko
Homo Interneticus
Форумчанин
 
Аватар для astecenko
 
Регистрация: 04.03.2011
Сообщений: 611
По умолчанию

Хм, странно.
У меня Delphi 7, в Classes буквально:
Код:
const
{ TFileStream create mode }

  fmCreate = $FFFF;
Файл созданный открыть не даёт - пишет "Файл занят другим процессом".

смотрите тут

Последний раз редактировалось astecenko; 16.10.2012 в 11:46.
astecenko вне форума Ответить с цитированием
Старый 16.10.2012, 11:53   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

astecenko, это было бы хорошо, если это было так просто.

Дело в том, что при использовании кода fmOpenReadWrite ( fmOpenReadWrite = 0002 )
наблюдается точно такая же ошибка с доступом к файлу:

проверьте:
Код:
  name := ExtractFileDir(Application.ExeName) + '\test.txt';
  Stream := TFileStream.Create(name, fmOpenReadWrite or fmShareDenyNone);
  Stream.Write(AnsiString('123456789')[1], 9);

  strl.LoadFromFile(name);

Цитата:
Сообщение от avd
Но, что интересно, блокнотом файл который
Код:
TFileStream.Create(name, fmCreate or fmShareDenyNone);
спокойно можно открыть!
Интересно всё-таки кто виноват в такой ситуации Delphi или API?
"я не в курсе, ребята..."
а попробуйте
а) дополнительное приложение на Delphi откроет такой файл?
b) если да - тогда попробуйте в дополнительном потоке открыть файл. Может операционка ограничивает доступ в пределах одного выполняемого потока (нити== thread)...

Последний раз редактировалось Serge_Bliznykov; 16.10.2012 в 11:57.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 16.10.2012, 12:00   #7
avd
Пользователь
 
Регистрация: 06.06.2010
Сообщений: 79
По умолчанию

Цитата:
а) дополнительное приложение на Delphi откроет такой файл?
В том-то и беда (для меня), что не открывает;
avd вне форума Ответить с цитированием
Старый 16.10.2012, 12:25   #8
astecenko
Homo Interneticus
Форумчанин
 
Аватар для astecenko
 
Регистрация: 04.03.2011
Сообщений: 611
По умолчанию

Проверил, на LoadFromFile все равно выскакивает ошибка, но дополнительное приложение на Delphi (TotalCommander Viewer) открывает
astecenko вне форума Ответить с цитированием
Старый 16.10.2012, 12:41   #9
avd
Пользователь
 
Регистрация: 06.06.2010
Сообщений: 79
По умолчанию

astecenco, спасибо за помощь.
Видимо беда со StringList. Я об этом даже не подумал.
Так всё работает:

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  Stream, strm: TFileStream;
  name: string;
begin
  name := ExtractFileDir(Application.ExeName) + '\test.txt';

  Stream := TFileStream.Create(name, fmCreate or fmShareDenyNone);
  Stream.Write(AnsiString('123456789')[1], 9);

  strm := TFileStream.Create(name, fmCreate or fmShareDenyNone);
  strm.Write(AnsiString('abcd')[1], 4);
  strm.Free;

  Stream.Free;
end;
Может StringList требует себе монопольный доступ к файлу, а он уже открыт (как-то так).

Последний раз редактировалось avd; 16.10.2012 в 12:52.
avd вне форума Ответить с цитированием
Старый 16.10.2012, 12:56   #10
astecenko
Homo Interneticus
Форумчанин
 
Аватар для astecenko
 
Регистрация: 04.03.2011
Сообщений: 611
По умолчанию

Цитата:
Сообщение от avd Посмотреть сообщение
Может StringList требует себе монопольный доступ к файлу, а он уже открыт (как-то так).
Так посмотреть же можно
Код:
procedure TStrings.LoadFromFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;
astecenko вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Удаление в dataGridView даёт ошибку. KatruKot C# (си шарп) 2 07.05.2012 10:21
Dataset - что даёт определение полей? DeveloPerchik БД в Delphi 11 07.04.2012 19:44
Программа не даёт выключить компьютер Shouldercannon Общие вопросы Delphi 3 22.08.2011 11:12
Канва не дает мне покоя:) NitroSki Компоненты Delphi 0 03.06.2011 10:19
c++ ..при компиляции даёт ошибку.. silveran Помощь студентам 6 17.05.2011 15:32