Опаковане на папки със ZLib
Опаковане на папки със ZLib.
Вероятно всеки е чел моята статия за пакетиране на файлове с помощта на библиотеката ZLib в Delphi. Той описва как можете да архивирате файлове с почти същото съотношение на компресия като ZIP. Но съм описал как могат да се архивират само отделни файлове. След многобройни искания от читатели, пиша друга статия за архивиране на цели папки.
За да архивираме папка, нека първо се научим как да лепим всички файлове, които се намират в папка. Нека първо разберем формата на този залепен файл и той ще бъде нещо подобно
Първите четири байта ще бъдат подписът, който ще означава, че това е файл от нашия формат
Следващите четири байта ще показват броя на файловете в този обединен файл
След това ще има масив от структури, които ще опишат всички файлове в този залепен файл, всяка структура ще има следния формат
В тази структура максималният размер на един файл може да бъде най-много 2 ^ 32 байта, т.е. 4 ГИГАБАЙТА. Между другото, за да подобрите образованието си, форматът за съхранение на низ, който използвам, се нарича LS, т.е. първо се записва дължината на низа, след това самият низ. Така че нека да стигнем до кодирането. Първо, трябва да получим списък с всички файлове в папката. Нека напишем функция, към която ще предадем пътя до папката и тя ще ни върне обекта TStringList, който ще съдържа списък на всички файлове в папката.
Първо създаваме обект с резултати и след това търсим всички файлове, които се намират в папката, пътят към който е предаден като втори параметър. Мисля, че тук няма нищо трудно. Първите два намерени файла се игнорират, защото са папки. и . при превключване към която оставаме в тази папка и се качваме съответно едно ниво нагоре.
След това създаваме обект, който ще съдържа списъка с подпапки и се извиква за всяка подпапка. Тук първите две точки се игнорират по малко по-различен начин, направих го само за промяна (между другото, това е много по-добре от това, което използвахме при търсене на файлове). След като получим списък с файлове във всяка подпапка, копираме получения списък в списъка с резултати.
В тази функция използвахме метода за извикване на функцията от самата нея, силно препоръчвам използването на този метод при извършване на операции, които изискват много голям брой извиквания на функции, тъй като това може да доведе до препълване на стека. В Windows стекът е ограничен до 1 MB. Следователно една функция (ако има един параметър) може да се извика само 131072 пъти, ще кажете „невъзможно е да се извика толкова много пъти“. И ако функцията има 5 параметъра, тогава 1048576/(6 * 4) = 34952. И това не е много. Ще попитате защо ни е необходим параметърът, който задава филтъра, аз ще отговоря „просто така“, никога не знаете какво може да ви е от полза. О, да, забравих да дам процедурата за получаване на списък с подпапки. Резултатният лист може да бъде върнат като резултат, но за промяна това също не боли.
Нека да отидем по-нататък ... след като получим списъка с файлове, трябва да обединим всички тези файлове в един. Умишлено ще отида, а не както казах в началото. Ще направим това: на нашата функция ще бъде предадена функция, която ще извърши някакво действие с файла, от който се нуждаете. Заглавката на функцията ще бъде такава