AssignFile(FileToWrite,MainFile.ArcName);
Try
Reset(FileToRead,1);
Rewrite(FileToWrite,1);
//Инициализируем массив строк в котором будут
//хранится кодовые слова
For i:=0 to 255 Do ArrOfStr[i]:='';
//Загоням в массив строк кодовые слова соответсвующие
//своим символам
For i:=0 to MainFile.Stat.CountByte do
Begin
ArrOfStr[MainFile.Stat.massiv[i]^.Symbol]:=
MainFile.Stat.massiv[i]^.CodWord;
Application.ProcessMessages;
End;
//узнаём какое целое количество буферов по 4 кбайт будет содержатся в
//сжимаемом файле
CountBuf:=MainFile.Size div Count;
//Сколько останется байт для записи не вошедших в ранее
//определённое значение CountBuf
LastBuf:=MainFile.Size mod Count;
Buffer:='';//обнуляем буфер
/////////////
CreateHead; //вызываем процедуру создания заголовка файла
/////////////
//фрмируем буфер кодовых слов
for i:=1 to countbuf do
Begin
//считываем из файла по 4 кбайт
BlockRead(FileToRead,buf,Count);
//////////////////////
For j:=1 to count do
Begin
//растим буфер из кодовых слов
buffer:=buffer+ArrOfStr[buf[j]];
//если длина buffer превысит значеие 8*4096 (это означает
//превысит размер выходного буфера размер которого 4096байт)
//мы вызываем процедуру записи в файл
If Length(buffer)>8*count
Then
WriteInFile(buffer);
Application.ProcessMessages;
End;
// ProgressBar1.Position:=100 div countbuf;
End;
//Запись оставшейся цепочки байт
If lastbuf<>0
Then
Begin
//считываем в массив из файла оставшиеся байты
BlockRead(FileToRead,buf,LastBuf);
//растим buffer строку из кодовых слов
For j:=1 to lastbuf do
Begin
buffer:=buffer+ArrOfStr[buf[j]];
If Length(buffer)>8*count
//если его размер превысит значение 8*4096 (а это может иметь
//место), то вызываем процедуру записи в файл
Then
WriteInFile(buffer);
Application.ProcessMessages;
End;
End;
//выываем процедуру записи оставшейся цепочки кодовых слов
WriteInFile_(buffer);
CloseFile(FileToRead);
CloseFile(FileToWrite);
Except
ShowMessage('Ошибка создания архива');
End;
End;
//главная процедура для создания архивного файла
Procedure CreateFile; //(802)
var
i: Byte;
Begin
With MainFile do
Begin
{сортировка массива байтов с частотами (192)}
SortMassiv(Stat.massiv,stat.CountByte);
{поиск числа задействованных байтов из массива
(ACSII) возмжных символов. В CountByte будем хранить
количество этох самых символов }
i:=0;//обнуляем счётчик
While (i<Stat.CountByte) //до тех пор пока счётчик
//меньше количества задействовнных байт CountByte
//и статистика байта (частота появления в файле)
//не равна нулю делаем
and (Stat.massiv[i]^.SymbolStat<>0) do
Begin
Inc(i); //увеличиваем счётчик на единицу
End;
//////////////////////
If Stat.massiv[i]^.SymbolStat=0 //если дошли до символа
//с нулевой встречаемостью в файле то
Then
Dec(i); //уменьшаем счётчик на единицу тоесть возвращаемся
//назад это будет последний элемент
//////////////////////
Stat.CountByte:=i;{присваиваем значение счётчика
CountByte. Это означает что в архивируемом файле используется такое количество из 256 возможных символов. Будет исползоватся для построения древа частот} {создание дерева частот. Передаём в процедуру начальные параметры Tree=nil-эта переменная будет содержать после работы процедуры древо ,Stat.massiv-массив с символами и соответствующей им статистикой,а так же указанием на правое и левой дерево,Stat. CountByte количество используемых символов в архивирумом файле (230)} CreateTree(Tree,Stat.massiv,Stat.CountByte); {запускаем в работу дерево с помощью его нахадим соответствующие кодовые слова. Суть алгоритма вызываем функцию SymbolToCodWord(Tree:TByte(указатель на корень дерева. Он у нас выработался в результате работы процедуры CreateTree, Symbol:byte):
String функция вернёт нам строку содержащую кодовое слово ()}
for i:=0 to Stat.CountByte do
Stat.massiv[i]^.CodWord:=SymbolToCodWord(Tree,stat.massiv[i]^.Symbol);
//пишем сам файл
CreateArchiv;
//Удаляем уже ненужное дерево
DeleteTree(Tree);
//Инициализируем статистику файла
MainFile.Stat.Create;
End;
End;
//Основная процедура сжатия файла
procedure RunEncodeHaff(FileName_: string);
begin
MainFile.Name:=FileName_;//передаём имя
//архивируемого файла в программу
StatFile(MainFile.Name); //запускем процедуру создания
//статистики (частоты появления того или иного символа)
//для файла (строка 274)
CreateFile; //вызов процедуры созданя архивного файла (737)
end;
//Основная процедура разархивирования файла
procedure RunDecodeHaff(FileName_: string);
begin
MainFile.name:=FileName_;//передаём имя
//архивируемого файла в программу
ExtractFile;//Вызываем процедуру извлечения архива
end;
end.