Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовая Архив.docx
Скачиваний:
16
Добавлен:
18.09.2019
Размер:
856.26 Кб
Скачать

Архивация

Техника работы из библиотекой zLib основана на потоках. Библиотека экспортирует класс TCustomZLibStream - потомок класса TStream. Класс TCustomZLibStream в свою очередь является родителем для TCompressionStream и TDecompressionStream. Работа с этими классами стандартна, и внимания заслуживают только их конструкторы.

Класс TCompressionStream для упаковки данных имеет конструктор:

constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream)

Тут перечисление:

TCompressionLevel = (clNone, clFastest, clDefault, clMax)

– степень сжатия, а Dest – поток назначения, куда будут записываться заархивированные данные.

Класс TDecompressionStream для распаковки имеет конструктор:

constructor Create(Source: TStream);

Тут Source – потока назначения, куда будут записываться распакованные данные.

Классы TCompressionStream и TDecompressionStream работают "на лету" в том смысле, что упаковка/распаковка и запись в принимающий поток осуществляется сразу по мере того как данные поступают на вход класса (для TCompressionStream) или считываются из него (для TDecompressionStream).

Замечание: Для того, чтобы во время работы программы не создавалось впечатление "подвисания" программы, я процедуры архивации и распаковки засунул в отдельные подпроцессы – нити.

Я не использовал встроенные средства в Delphi для работы с нитями, а воспользовался своими любимыми API-функциями. Для создания нити используется CreateThread:

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes, // дескриптор защиты

SIZE_T dwStackSize, // начальный размер стека

LPTHREAD_START_ROUTINE lpStartAddress, // функция потока

LPVOID lpParameter, // указатель переменной, что может передаваться в поток

DWORD dwCreationFlags, // опции создания

LPDWORD lpThreadId // идентификатор потока

);

Это определение я взял из MSDN, думаю, оно вполне понятно. Для нас важны параметры lpStartAddress, и dwCreationFlags.

-Параметр lpStartAddress – это указатель на функцию, которая будет выполняться в потоке.

-Параметр dwCreationFlags – определяет условия создания потока. Если установить сюда значение CREATE_SUSPENDED, то создается поток в состоянии ожидания и не запускается до тех пор, пока не будет вызвана функция ResumeThread. Если это значение нулевое, поток запускается немедленно после создания. В это время, никакие другие значения не поддерживаются.

-Функция CreateThread вовращает дескриптор потока, который мы можем использовать для различных целей (например, поменять приоритет или "прибить" поток функцией TerminateThread).

Практическая часть

Функция архивации:

function TForm1.SaveToZUP(filein,fileout:string;compression:TCompressionLevel):boolean;

Var //filein,fileout - входной и выходной файлы;

//compression - степень сжатия

ms:TMemoryStream; //вспомогательный поток, куда будет загружен входной filein

OutFile:TStream; //выходной поток, сюда поток архивации записывает сжатые данные

ZStream: TCustomZLibStream; //поток архивации (взял абстрактный)

filename:string[255]; //имя входного файла, его запишем в заголовок архива

begin

try

ms:=TMemoryStream.Create; //создание потока

ms.LoadFromFile(filein); //грузим входной файл в поток

OutFile:=TFileStream.Create(Fileout,fmCreate); //создадим пустой файл архива

filename:=ExtractFileName(filein); //выделим имя

OutFile.Write(filename,sizeof(filename)); //запишем в заголовок архива имя

try //создание архивирующего потока, запись данных будет идти в OutFile

ZStream:=TCompressionStream.Create(compression,OutFile);

try

ZStream.CopyFrom(ms,0); //копируем весь входной файл в архивирующий поток

//параллельно идет запись в OutFile

finally

ZStream.Free;

end;

finally

ms.free;

OutFile.Free;

result:=true;

end;

except result:=false;

end;

end;