Read and Seek

Načítavanie mnohotvarých súborov

Hard DiskÚvod

Posledné dva dni [pisane asi okolo 20. marca 2008] som strávil... Fuj, to vyznie akoby som naozaj celé dni robil len to jedno; čo nie je pravda. V skutočnosti sa jedná len o dva-či-tri dvoj-či-trojhodinové bloky. Ehm.

Znova: Posledné dva dni som strávil písaním kódu pre triedu TVSPProject. V čase, keď píšem tieto riadky, je kód hotový (pokúsim sa o nemožné - odhad v oblasti programovania) asi tak na 40 percent. Tí čo majú za sebou už akési programovanie môžu tušiť, aké je šialené vysloviť takýto odhad. Smrteľník nemôže predsa ani tušiť, kedy sa v programovom kóde zasekne, zamotá a obesí. (Keby to bolo ináč, nemali pri programátori také množstvá nedokončených projektov porozhadzovaných po disku.)

Trieda TVSPProject by mi časom mala poskytovať krásny, hladký prístup k obsahu a funkciám akéhokoľvek VSP projektu. Pod akronymom VSP (čo je vlastne koncovka súborov daného typu) rozumieme Viresol Project, samozrejme. Taktiež, samozrejme, všetci rozumieme, že Viresol je úžasný program, ktorý som vytvoril vo voľných chvíľach posledných troch rokov (Jééžiš, to už toľko?) a slúži na vizualizáciu rôznych projektov (okrem množstva iných záležitostí).

Z čoho sa skladá súbor Viresol projektu

Vo Viresole, konkrétne v jeho moduli Visualizer, si môže užívateľ vytvoriť nový projekt vizualizácie, ktorý založí na akomsi zdrojovom obrázku JPG, ktorý by mal, logicky, vykresžovať predmet nášho záujmu - teda, chceme pre neho vytvoriť vizualizáciu.

Vytvoríme si vrstvy (podobne ako vo Photoshop-e), vytvoríme si masky vrstiev, vyberieme si farby, pohráme sa trebárs aj s textúrami, a potom sa už len kocháme výslednou vizualizáciou. Inými slovami, uvidíme predmet nášho záujmu (ktorého podobu sme Viresolu predali v JPG obrázku pri tvorbe projektu) vykreslený v iných farbách, poprípade aj s použitím textúr.

Celý projekt sa potom dá uložiť do súboru s koncovkou VSP. Teda odtiať ten názov triedy TVSPProject. Čo v takom súbore ale je?
Text, teda údaje ako názov projekt, tvorca, popis, atď... Dátum vytvorenia, zámok proti prepisovaniu, a kadeaké iné informácie opisujúce štruktúru súboru. Čo ešte?

Obrázky, teda tých je viac typov: JPG, BMP, BM8 a je dosť možné, že časom včlením aj 32 bitové TGA obrázky (kôli ich alfa-kanálu).
Ako JPG ukladám kópiu originálneho súboru, na ktorom je projekt založený, ďalej mapu tieňov (textúry) a hopsa-hejsa to je všetko. Aspoň pre verziu súborov 3.2, ktorá je zatiaľ najnošia (už asi rok a pol, ak nie dva). To je všetko čo sa JPG obrázkov týka. Ešte sa skladujú:
Bitmapy, teda formát BMP, ktorý používam pre ľahké a rýchle uloženie malých náhľadov na jednotlivé farebné variácie vizualizácií. Čo ešte?
BM8 súbory, ktoré sú špecialita. Sám som si vytvoril takýto šikovný formát pre ukladanie dvojfarebných obrázkov - popisujú masku vrstvy, jednoducho čiernymi a bielymi bodmi. Nijak raz som nemohol bez straty (teda JPG kompresia nepricházala v úvahu) uložiť tieto „obrázky“. 1-bitové bitmapy problém neriešili, GIF ma tiež nepotešil, tak mi neostávalo nič iné, než si prispôsobiť nový grafický formát BM8 mojim potrebám.

Čo ešte? Rôzne dátové štruktúry opisujúce jednotlivé vrstvy a variácie, a rozľahlé bloky prídavných (z veľkej časti hluchých) dát popisujúcich vrstvy do väčšieho detailu.

Uloženie je ľahké

Zoberiem si prázdny súbor a začnem do neho sypať, rad-radom, čo len treba. O to sa stará Viresol. Je to jediná aplikácia, ktorá dokáže tieto projekty vytvárať. Však (aj) na to bol stvorený.

No načítavať tieto súbory pre rôzne dôvody bude viacero aplikácií a pre môj komfort, trieda TVSPProject bude poskytovať všetky parádne funkcie, bez toho aby som sa musel babrať s tajomstvami štruktúry VSP súborov a ich načítavaním. To však najprv budem musieť túto triedu napísať.

Hra na read and seek

V angličtine sa detská „hra na schovku“ nazýva „hide and seek“ a z veľkej miery sa načítavanie VSP projektov hre na schovku podobá. Rôzne časti projektu su v rôznych formátoch porozhadzované po rôznych častiach súboru. Pri programovaní to potom vyzerá ako hra na „read and seek“. Až pri písaní kódu som si uvedomil, aké množstvo hľadania (seek) a čítania (read) je nutné pre obdržanie požadovaných súborov a dát.

Rozhodol som sa všetky operácie vykonávať v pamäti (RAM, našťastie, a nie mojej), aby to bežalo pekne rýchlo. Jeden nutný read z disku (časovo náročná operácia v porovnaní read-ov z RAM pamäte) vykonám jednorázovo pri načítaní projektu.

function TVSPProject.loadFromFile(AFileName: TFileName): boolean;
var fs: TFileStream;
begin
result := false;
if (FileExists(AFileName)) and
(FMemoryStream<>nil) and
(FMemoryStream.position=0)then
begin
try
fs := TFileStream.Create(AFileName, fmShareDenyNone);
FMemoryStream.CopyFrom(fs,fs.Size);
result := true;
finally
FreeAndNil(fs);
end;
end;
end;

V ukázanom kóde sa vyskytuje niekoľkonásobná referencia na akýsi FMemoryStream, ktorého objekt (typu TMemoryStream) je vytvorený súčasne pri tvorbe samotného objektu typu TVSPProject.

Priznám sa, že dosť veľkú časť ozajstného kódu z mojej rozpísanej verzie triedy TVSPProject, som upravil, vynechal, atď. Pre kompletnosť predchádzajúceho úryvku kódu dodám aj interface triedy a zjednodušenú implementáciu jej konštruktora a deštruktora.

Interface

Uses ... //zoznam unitov, ktore potrebujeme importovat do nasho kodu

TVSPProject = class
private
FMemoryStream: TMemoryStream;
public
constructor Create;
destructor Destroy; override;
function loadFromFile(AFileName: TFileName): boolean;
end;

implementation

constructor TVSPProject.Create;
begin
FMemoryStream := TmemoryStream.Create;
inherited Create;
end;

destructor TVSPProject.Destroy;
begin
if FMemoryStream<>nil then
FreeAndNil(FMemoryStream);
inherited Destroy;
end;

... //nebudem tu znova opakovat implementaciu funkcie loadFromFile

Všetko čo sa odohráva vo funkcii loadFromFile je v podstate len načítanie celého obsahu súborového toku (súboru s cestou AFileName) do pamäťového toku FMemoryStream, ktorý si každý objekt typu TVSPProject vytvorí pri svojom vzniku.

Nedokončené. Prípadné otázky k danej tematike mi pokojne môžete zaslať e-mailom kliknutím na linku Kontakt.

Posledná úprava ( Saturday, 29 March 2008 )
 
< Predchádzajúca   Ďalšia >