|
||||||||
|
Копирование (продолжение).
Копирование (продолжение) и сжатие Существует такая штука, как сжатие данных. Хорошо, если вы инсталлируете свою программу с компакт-диска. Как правило, в такой ситуации вы не знаете, что ещё записать на эту бездонную болванку и несколько лишних мегабайт вам в данной ситуации совсем не помешают :) Совершенно по другому обстоят дела с дискетами. На дискеты надо помещать сжатую информацию в этом случае вся ваша программа возможно (только возможно) влезет всего лишь на тридцать четыре дискеты. Вот как делать сжатие это вопрос. Я расскажу вам о нескольких методах сжатия данных, которыми вы можете воспользоваться. Метод номер раз это сжатие файлов стандартными утилитами, разработанными фирмой Microsoft. Когда-то это была программа compress.exe (9554), сейчас cabarc.exe (35703). hInFile := LZOpenFile(PChar(SourcePath), ofInReOpenBuff, OF_READ); hOutFile := LZOpenFile(PChar(TargetPath), ofOutReOpenBuff, OF_CREATE or OF_WRITE); iLZError := LZCopy(hInFile, hOutFile); if iLZError > 0 then // Операция выполнилась успешно, скопировано iLZError байт else // Ошибка номер iLZError LZClose(hOutFile); LZClose(hInFile); Метод номер два сжатие файлов с помощью библиотеки ZLib, которая поставляется вместе с Delphi (она находится в каталоге \Info\Extras\ZLib оригинального диска с Delphi 3.0). Она предоставляет вам два класса, которые являются наследниками TStream. Вы можете воспользоваться кодом функции копирования при помощи TFileStream из предыдущей статьи для того, чтобы реализовать как сжатие, так и распаковку произвольного потока (в том числе и файла). Ещё один метод использование динамической библиотеки unrar.dll (27336), разработанной Евгением Рошалом. Существуют и другие библиотеки (даже компоненты), вы можете свободно найти их, если будете достаточно долго шляться по Интернету. Описание функций, предоставляемых библиотекой unrar.dll, вы обнаружите здесь. Примечание: Мне кажется, что менее всего размер вашей инсталляции увеличится, если вы используете методы, предлагаемые Microsoft; ровно потому, что они встроены в Windows и вам не надо записывать их на дискету. Копирование нескольких файлов представляется достаточно простым, раз уж мы научились копировать один файл. Наиболее просто это делается, если ваши файлы поставляются в одном архиве (.CAB или .RAR). Сложным может показаться копирование файлов по маске (*.*) и копирование вложенных подкаталогов. Ниже приводится исходный текст процедуры, которая составляет список файлов в каталоге и всех вложенных подкаталогах. procedure ReadTree(Path: String; Strings: TStrings); procedure ReadFolder(Path: String; Strings: TStrings); var SearchRec: TSearchRec; FindResult: Integer; begin FindResult := FindFirst(Path + '*.*', faAnyFile, SearchRec); while FindResult = 0 do begin // Если найден подкаталог, рекурсивно читаем его содержимое // Не забываем игнорировать подкаталоги '.' и '..' with SearchRec do if (Name <> '.') and (Name <> '..') then begin Strings.Add(Path + Name); if (Attr and faDirectory <> 0) then ReadFolder(Path + Name + '\', Strings); end; FindResult := FindNext(SearchRec); end; FindClose(SearchRec); end; begin // Эта процедура заносит в Strings список файлов во всех вложенных папках // каталога Path и сами эти папки Strings.Clear; if (Length(Path) > 0) and (Path[Length(Path)] <> '\') then Path := Path + '\'; ReadFolder(Path, Strings); end; Если вам что-то непонятно, смотрите пример использования (2345 байт) этой функции. Отдельно стоит поговорить о тех файлах, которые могут использоваться сразу несколькими программами. Для этих файлов существует даже специальное название разделяемые (поскольку несколько программ делят их между собой). Обычно они записываются в системный каталог Windows (для Windows 95 это как правило \WINDOWS\SYSTEM, для Windows NT \WINNT\SYSTEM32). Если системный каталог доступен только для чтения, то эти файлы необходимо записывать в каталог Windows (\WINDOWS и \WINNT соответственно), который всегда доступен для записи. function GetSysDir: String; var szPath: array [0..MAX_PATH - 1] of Char; I: Integer; Stream: TStream; begin // Получаем системный каталог GetSystemDirectory(szPath, MAX_PATH); Result := StrPas(szPath); // Добавляем обратный слеш в конец пути, если его там нет if (Length(Result) > 0) and (Result[Length(Result)] '\') then Result := Result + '\'; // Подбираем имя файла вида XXXXXXXX.TMP, где XXXXXXXX --- // шестнадцатиричное число, который не существует в системном каталоге I := 0; while FileExists(Result + IntToHex(I, 8) + '.TMP') do Inc(I); try // Создаём файл и удаляем его. Если всё нормально, то каталог доступен // для записи. Stream := TFileStream(Result + IntToHex(I, 8) + '.TMP', fmCreate); Stream.Free; DeleteFile(Result + IntToHex(I, 8) + '.TMP'); except // Если создать файл не удалось, в качестве системного каталога будем // использовать каталог Windows. GetWindowsDirectory(szPath, MAX_PATH); Result := StrPas(szPath); if (Length(Result) > 0) and (Result[Length(Result)] '\') then Result := Result + '\'; end; end; Если разделяемый файл уже существует в целевом каталоге, то необходимо сравнить версии, языки и др. характеристики двух файлов и на основании этого сравнения решать копировать файл или не надо. При копировании разделяемых файлов требуется уведомить Windows о том, что одним разделением стало больше. Это делается через реестр. При замещении файлов, которые в момент инсталляции используются Windows требуется определённая техника, поскольку перезаписать занятый файл нельзя. Эти вопросы в ближайшее время будут освещены в следующей статье. Поистине, копирование файлов тема неисчерпаемая :) Напоследок, исследуем вопрос о том, куда копировать файлы? В соответствии с рекомендациями Microsoft, каталог вашей программы должен иметь форму <Program Files>\<Название вашей фирмы>\<Название продукта>. Вы можете также включить в название каталога информацию о версии продукта, например C:\Program Files\Borland\Delphi 3, хотя возможен и вариант C:\Program Files\Borland\Delphi\3 (реально фирма Borland использует первый вариант). Бывают и исключения, в частности FAR Евгения Рошала ставится в C:\Program Files\FAR. Разделяемые файлы следует копировать в системный каталог Windows, а если он защищён от записи в каталог Windows. А сейчас мы переходим к реестру.
| |||||||||
За содержание страницы отвечает Гончарова М.Н. © Кафедра СПиКБ, 2002-2017 |