Открытие файла только для чтения

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Открытие файла только для чтения

Сообщение Troublemaker » 30.05.2008 01:17:32

Специально воспользовался поиском с разными параметрами - не нашел ничего вразумительного.

Итак:
Код: Выделить всё
procedure TEditForm.FileNameEdit1AcceptFileName(Sender: TObject;
  var Value: String);
var LocFS:TFileStream;
begin
  ShowMessage(Value);
  LocFS.Create(Value,fmOpenRead);
Затыкается на этой строчке. Смотрю в streams.inc:
Код: Выделить всё
constructor TFileStream.Create(const AFileName: string; Mode: Word);

begin
  FFileName:=AFileName;
Умирает на этом месте, уходя в i386inc::fpc_AnsiStr_Decr_Ref
Код: Выделить всё
Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer); [Public,Alias:'FPC_ANSISTR_DECR_REF']; compilerproc; nostackframe; assembler;
asm
        cmpl $0,(%eax)
        jne .Ldecr_ref_continue
        ret
.Ldecr_ref_continue:
// Temps allocated between ebp-24 and ebp+0
        subl    $4,%esp
// Var S located in register
// Var l located in register
        movl    %eax,(%esp)
// [101] l:=@PAnsiRec(S-FirstOff)^.Ref;
        movl    (%eax),%edx
        subl    $8,%edx
// [102] If l^<0 then exit;
        cmpl    $0,(%edx)


value получаем через TFilenameEdit, value='D:\RCIMAGE.ISO'.

Что бы это значило?

ВОобще, задача тривиальная: получить размер файла по его имени. Причем - не важно, открыт ли он сейчас кем-нибудь или нет, хочу открывать в RO/DenyNone только для определения размера. Со стримами начал возиться потому что reset(file) вылетает независимо от filemode в ситуации, когда файл кем-то открыт.
Имя, переданное в value, реальное. Файл существует, размер около 10М, не открыт никем вообще, лежит в корне fat32-диска. КОнкретно с ним связка assign/reset работала нормально.

Добавлено спустя 1 минуту 30 секунд:
В крайнем, конечно, случае, воспользуюсь findfirst, но это же изврат
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Открытие файла только для чтения

Сообщение Максим » 30.05.2008 02:14:18

Что бы это значило?

Вместо
Код: Выделить всё
LocFS.Create(Value,fmOpenRead);

следует употреблять
Код: Выделить всё
LocFS:=TFileStream.Create(Value,fmOpenRead);
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 598
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Re: Открытие файла только для чтения

Сообщение Troublemaker » 30.05.2008 02:28:51

Блин! На фига тогда вообще наследуется .create! :-(

Добавлено спустя 24 минуты 49 секунд:
Однако, задача никуда не делась: так как же открыть файл только для чтения, если никто, конечно, не держит его в режиме rw/denyall ?
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Открытие файла только для чтения

Сообщение Максим » 30.05.2008 04:47:28

Наследование Create нормально работает. Такое создание экземпляров класса связано с их расположением не в стеке, а в куче. Память под них выделяется только в момент создания экземпляра. Поэтому конструкция
Код: Выделить всё
LocFS.Create(Value,fmOpenRead);
просто не имеет смысла. Но она приобретает смысл в случае работы с объектами (object).

Кстати, это всё описано в документации FPC.

По поводу открытия на чтение:
Код: Выделить всё
LocFS:=TFileStream.Create(Value,fmOpenRead);
должен с этой задачей справиться?
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 598
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Re: Открытие файла только для чтения

Сообщение Vadim » 30.05.2008 05:05:39

Troublemaker писал(а):ВОобще, задача тривиальная: получить размер файла по его имени.

Ну и зачем для этого открывать файл, если можно воспользоваться FindFirst()?
Или Вы не всё рассказали? :)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Открытие файла только для чтения

Сообщение alexs » 30.05.2008 10:45:30

Посмотри модуль FileUtil - там очень много интересного. :D
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Открытие файла только для чтения

Сообщение Vadim » 30.05.2008 11:51:20

alexs писал(а):...FileUtil...

А он именно так называется или как-то по другому?
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Открытие файла только для чтения

Сообщение alexs » 30.05.2008 13:42:39

Именно так. Это часть LCL и находится в каталоге lcl
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Открытие файла только для чтения

Сообщение shade » 30.05.2008 14:03:48

Troublemaker писал(а):Блин! На фига тогда вообще наследуется .create!

В данном случае Create - конструктор класса
TStringList.Create - создает экземпляр (выделяет память, инициализирует VMT и поля которые необходимо инициализировать, например AnsiString/WideString), вызывает конструктор и возвращает сконструированный объект.

obj.Create - не создает экземпляр (не выделяет память, не трогает VMT и т.п.), а просто вызывает конструктор как обычный метод. Такой вызов в основном используется при наследовании - чтобы конструктор класса вызывал конструктор родителя.

Например
Код: Выделить всё
constructor TSomeClass.Create;
begin
  // инициализация родителя
  inherited Create; // объект уже скоструирован, потому родительский конструктор вызывается как обычный метод.
  // инициализация потомка
  ...
end;


Почти аналогично с деструктором.
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Re: Открытие файла только для чтения

Сообщение Troublemaker » 30.05.2008 14:20:40

shade писал(а):Такой вызов в основном используется при наследовании - чтобы конструктор класса вызывал конструктор родителя
Спасибо за разъяснение, теперь стало понятнее.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Открытие файла только для чтения

Сообщение Vadim » 02.06.2008 07:40:49

alexs писал(а):Это часть LCL и находится в каталоге lcl

Ага, нашёл. :)
Я думал, что этот модуль из FreePascal и там его искал... :)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru