Budeme se věnovat práci s archivy, zejména pak rozbalování a zabalování. Zajímat nás budou nejrozšířenější formáty tar, zip a rar.
12.7.2010 00:00 | Jiří Václavík | přečteno 15196×
Podívejme na to, jak manipulovat s TAR, ZIP a RAR v Perlu.
Budeme používat zejména modul Archive::Tar, jelikož tento typ archivu je v linuxovém světě asi nejrozšířenější.
Archive::Tar je sice jako modul pomalý a občas náročný na paměť, ale díky implementaci pomocí perlu je snadno přenositelný.
Pro jakoukoliv manipulaci s archivy je třeba vždy vytvořit Tar objekt. To se dělá standardní cestou metodou new.
$tar = Archive::Tar->new("priklad.tar");
Je-li uvedeno jméno archivu jako parametr, pak se z něj provedením tohoto příkazu se do operační paměti načte seznam souborů. S těmito soubory tak můžeme dále pracovat.
Pro vymazání seznamu souborů z paměti lze využít metodu clear a pro znovunačtení metody read.
Přidávání se provádí metodou add_files a přejmenování pomocí rename.
Pomocí metody contains_file lze ověřit, zda archiv obsahuje zadaný soubor.
$tar->contains_file("index.html");
Chceme-li zkontrolovat celý obsah, pak oceníme spíše funkci list_files, která vrátí seznam názvů všech souborů.
Pokud se nechceme obtěžovat s vytvářením objektů, lze pro získání seznamu souborů v archivu archiv.tar zadat také následující.
Archive::Tar->list_archive("archiv.tar");
Metoda read slouží k načtení komprimovaného souboru do paměti. Jejími argumenty jsou jméno komprimovaného souboru a jako třetí parametr odkaz na hash s pevně určenou strukturou, který ovlivní, kolik a jaké soubory mají být z vybaleny z archivu.
Návratová hodnota funkce read je pole obsahující názvy rozbalených souborů.
Po volání read máme obsah k rozbalení načten v paměti. Samotné rozbalení provede jedna z metod extract nebo extract_file.
Podívejme se na možné klíče hashe parametrů ve volání metody read.
Klíč | Význam |
filter | pomocí regulárního výrazu určí, vybere jen některé soubory |
extract | nastavíme-li hodnotu na 1, pak se automaticky zavolá metoda extract (a archiv bude rozbalen) |
limit | omezí počet rozbalovaných souborů na uvedené množství |
Chceme-li rozbalit soubor priklad.tar, pak tedy dle výše uvedeného napíšeme následující kód.
use Archive::Tar;
my $tar = Archive::Tar->new;
$tar->read("priklad.tar");
$tar->extract();
Uvedeme-li parametr extract s pravdivou hodnotou, pak lze program zredukovat o poslední řádek.
use Archive::Tar;
my $tar = Archive::Tar->new;
$tar->read("priklad.tar", "", {"extract"=>1});
Pro rozbalení pouze souborů s příponou html použijeme klíč filter.
$tar->read("priklad.tar", "", {"extract"=>1, "filter"=>'.*html\$'});
Pro vybalení jednoho souboru zde máme metodu extract_file. Zde můžeme jako druhý parametr zadat, kam se má vybalený soubor přesunout.
Pokud nám jde pouze o rozbalení běžného archivu, pak jistě oceníme metodu třídy extract_archive. Ta funguje následovně.
Archive::Tar->extract_archive("priklad.tar");
Soubor rozbalený pomocí Archive::Tar se stává objektem typu Archive::Tar::File. To nám přináší zejména možnost filtrovat soubory podle dalších kritérií.
Uveďme si některá kritéria v tabulce.
Kritérium | Význam |
name | jméno souboru |
size | velikost souboru v bajtech |
type | typ souboru; Archive::Tar pro tento účel exportuje konstanty FILE, HARDLINK, SYMLINK, CHARDEV, BLOCKDEV, DIR, FIFO, SOCKET |
mktime | čas poslední modifikace |
mode | mód |
uid, gid, uname, gname | uživatel, skupina vlastnící soubor |
Pak lze provádět takové věci jako například rozbalení souborů, jejichž velikost nepřesahuje 1000 bajtů. To by se provedlo takto.
$tar->extract(grep {$_->size < 1000 } $tar->get_files);
Taktéž lze rozbalovat podle obsahu souboru. Existuje metoda get_content, jež vrací obsah souboru. Pro rozbalení pouze těch souborů, které obsahují slovo linuxsoft provedeme následující příkaz.
$tar->extract(grep {$_->get_content =~ /linuxsoft/i} $tar->get_files);
Existují další zajímavé metody pro objekty typu Archive::Tar::File, o nichž se lze dočíst v dokumentaci.
Do tvořeného archivu se vždy vloží soubory, které jsou aktuálně v paměti. Ovšem jak přidat další soubory? K tomu máme metodu add_files, které předáme seznam souborů.
Přidání souboru tar.pl do našeho virtuálního seznamu tak provedeme následujícím voláním.
$tar->add_files("tar.pl");
Archivy se zabalují metodou write. Musíme vždy uvést co zabalit a jak to zabalit.
Prvním argumentem určujeme soubor, kam se archiv zapíše. Druhým je pro gzip úroveň komprese od 1 nebo 9 nebo pro bzip2 hodnota COMPRESS_BZIP.
Pro vytvoření nového archivu ze souborů v paměti lze užít například následující příkaz.
$tar->write("novy_archiv.tgz", 9);
Rychlejší cesta pro vytvoření archivu vede přes metodu třídy. Aniž bychom vytvářeli objekt, můžeme volat metodu create_archive. Té předáme požadovaný název výsledného archivu, typ komprese a seznam souborů, které chceme zabalit. Na ukázku přiložme tento příkaz.
Archive::Tar->create_archive( "vysledek.tgz", COMPRESS_GZIP, "tar.pl", "formular.html");
Myšlenka u práce se ZIP archivy je podobná jako u TAR archivů a proto se v rychlosti podívejme na základní operace.
Opět je třeba na začátku načíst archiv, který budeme rozbalovat. To provedeme pomocí metody new.
use Archive::Zip;
my $zip = Archive::Zip->new("archiv.zip");
Poznamenejme, že i zde je k dispozici metoda read, kterou lze přidávat nové soubory z archivů.
Seznam souborů z archivu archiv.zip nyní máme k dispozici. Pro seznam jmen souborů z tohoto archivu stačí zavolat metodu memberNames.
print $zip->memberNames;
Rozbalení proběhne po zavolání metody extractMember. Jako parametr uvedeme seznam souborů, které se mají rozbalit.
$zip->extractMember("titulky.sub");
Se seznamem souborů můžeme volně manipulovat. Pro odstranění některého souboru použijeme metodu removeMember.
$zip->removeMember("nepotrebny_soubor");
Naopak pro přidání souboru využijeme metodu addFile. Do nově tvořeného archivu lze nový soubor přidat pod změněným jménem.
$zip->addFile("data", "nove_jmeno")
Máme-li seznam souborů připraven, můžeme je zabalit.
$zip->writeToFileNamed("vysledek.zip");
Možností Archive::Zip je více. Pokročilejší záležitosti lze nalézt v dokumentaci.
Pro rozbalení RAR archivu lze použít následující sekvenci příkazů.
use Archive::Rar;
$rar = Archive::Rar->new(-archive => "archiv.rar");
$rar->List;
$rar->Extract;
Existuje univerzální modul Archive::Extract, který dokáže rozbalit soubory různých typů. Jeho použití je následující.
use Archive::Extract;
$extract = Archive::Extract->new(archive => "priklad.tar");
$extract->extract;
Naopak dalším modulem zaměřeným na vytváření archivů je Archive::Builder.
Mimo uvedené existuje řada dalších modulů tvaru Archive::.