Научная работа

DELPHI:Работа с файлами
Сазонов Д.О.

Здравствуйте уважаемые читатели нашего журнала! Эта рубрика полностью посвящена фанатам Delphi и вообще PASCAL(я). Таким образом рубрика в основном рассчитана на пользователей уже имеющих определенный опыт работы с Delphi и PASCAL, но надеюсь она будет интересна и тем кто только собирается познакомится с этими языками. Сегодня я постараюсь рассказать Вам, как в Delphi организуется работа с файлами при помощи так называемых "диалоговых коробок" (DialogBox).
Итак, задача будет следующей: открыть на диске любой файл, заменить в нем все символы с кодами <32 на 32 и записать в отдельный файл.

1. Создаем форму и добавляем на нее два компонента из вкладки Dialogs - OpenDialog и SaveDialog
2. Далее на панели Object Inspector выбираем элемент Form1, открываем вкладку methods и дважды щелкаем на методе OnCreate - этот метод вызывается когда создается форма т.е. программа.


Далее соответственно пишем текст процедуры, который будет выполняться при запуске програмы.

procedure TForm1.FormCreate(Sender: TObject);
  var r,w:file of byte;
      b:byte;
begin
   if OpenDialog1.Execute then
      begin
        SaveDialog1.Execute;
           AssignFile(r, OpenDialog1.FileName);
           AssignFile(w, SaveDialog1.FileName);
             Reset(r);
             Rewrite(w);
               //меняем коды
             while not (eof(r)) do
               begin
                 Read(r,b);
                  if b<32 then b:=32;
                 Write(w,b);
               end;
           CloseFile(w);
           CloseFile(r);
       end;
Application.Terminate;
end;
Единственное на чем здесь необходимо заострить внимание - это SaveDialog1.Execute, OpenDialog1.Execute;
А свойства SaveDialog1.FileName и Open:.FileName возвращают имя выбранного вами файл с помощью DialogBox.

Рассмотрим иерархию классов этих компонентов. Ну во первых это разумеется наследник Tcomponent(Tobject), который в свою очередь является предком TcommonDialog. А от TcommonDialog и идут методы TSaveDialog и TOpenDialog и что самое интересное TOpenDialog является предком для TsaveDialog. Рассмотрим то, что скрывает от нас Object Inspector -есть 13 методов объявленных как Protected и недоступных на общее обозрение. Среди них и функция Execute - да именно функция т.к. она возвращает значение True - если все прошло успешно, а в противном случае False, oна то нас и будет интересовать. Так как метод TsaveDialog отличается от Topen: только этой функцией, она сделана виртуальной. Рассмотрим различие в функциях у предка и потомка.

function TOpenDialog.Execute: Boolean;
begin
  Result := DoExecute(@GetOpenFileName);
end;

function TSaveDialog.Execute: Boolean;
begin
   Result := DoExecute(@GetSaveFileName);
end;
Как видим виртуальный метод отличается только параметрами посылаемыми в функцию DoExecute. Но не надо думать что именно эта функция открывает и считывает файл, она лишь организует совместимость Delphi со встроенной процедурой windows GetOpenFileName. Процедура DoExecute переводит параметры строки в доступный Windows формат, заменяет символы с кодом #0, на символ "|", для того чтобы можно было загружать несколько файлов сразу и т.д. Сами же процедуры GetOpen: и GetSave импортируются из библиотеки comdlg32.dll находящейся в каталоге \windows\system Вот все процедуры этой библиотеки:

0000    00005f4f  ChooseColorA
0001    00006824  ChooseColorW
0002    00005fe5  ChooseFontA
0003    00006830  ChooseFontW
0004    00006092  CommDlgExtendedError
0005    0000575e  FindTextA
0006    0000680c  FindTextW
0007    00004f99  GetFileTitleA
0008    00006848  GetFileTitleW
0009    00001162  GetOpenFileNameA
0010    000067f4  GetOpenFileNameW
0011    00004f8b  GetSaveFileNameA
0012    00006800  GetSaveFileNameW
0013    0000689e  PageSetupDlgA
0014    0000683c  PageSetupDlgW
0015    00001298  PrintDlgA
0016    00006892  PrintDlgW
0017    0000576c  ReplaceTextA
0018    00006818  ReplaceTextW
0019    00004f99  WEP
Всего 19. Итак Delphi просто посредник между нами и внутренними структурами windows и пока что ему нет равных ни по скорости ни по компактности сжатия данных среди объектных языков под Windows.
Теперь рассмотрим как работает свойство FileName. Когда мы вызываем OpenDialog1.FileName мы можем получить имя файла, но не стоит думать, что это делает FileName, на самом деле этим занимается PRIVATE (из-за чего вы никогда не сможете ей воспользоваться напрямую) функция GetFileName. Вот как она выглядит:

function TOpenDialog.GetFileName: TFileName;
var
  Path: array[0..MAX_PATH] of Char;
begin
  if NewStyleControls and (FHandle <> 0) then
  begin
    SendMessage(GetParent(FHandle), CDM_GETFILEPATH, SizeOf(Path), Integer(@Path));
    Result := StrPas(Path);
  end
  else Result := FFileName;
end;
Как видно из примера эта функция может работать только под windows 95 и не обеспечивает совместимость с win3.11 (:if NewStyleControls and (FHandle <> 0) then :.) - это только лишь помогает устранить "глюки" и система работает более стабильно. Дальше функция обращается к системе windows и генерирует системный вызов, с помощью которого в переменную Path помещается имя файла. Теперь опять идет обращение к файлу, но нам не надо самим писать всю эту процедуру, это сделает за нас Delphi. Delphi является как бы дополнением Windows, обрабатывая всё по своему и гораздо лучше чем это делает сама winodws. К сожалению ошибки и "глюки" присущие windows, Delphi исправить не может, стало быть остается ждать когда выйдет обещанный пакет Inprise Delphi для Linux.
Исходный текст программы можно скачать Здесь!