Přejít k navigační liště

Zdroják » Webdesign » Práce se soubory v prohlížeči, díl 2

Práce se soubory v prohlížeči, díl 2

Články Webdesign

V předchozím článku jsme podrobně probírali třídy Blob, File a metody rozhraní FileReader. Ukázali jsme si, jak v prohlížeči otevřít soubor, předaný buď pomocí drag-n-drop, nebo pomocí INPUT FILE. V dnešním pokračování si ukážeme možnosti vytváření souborů v prohlížeči a jejich ukládání, jak na server, tak na místní disk.

Rozhraní File Writer API slouží k vytváření souborů v prohlížeči a jejich přípravě pro další práci. Skládá se z BlobBuilderu, což je nástroj pro „vytváření souborů v paměti“, a dvou nástrojů, FileSaver a FileWriter, kde oba mají ještě synchronní verzi (FileSaverSync, resp. FileWriterSync). A protože se pohybujeme v místech, kde ještě není specifikace pevná, tak nepřekvapí, že jméno metody saveAs() z FileSaverSync se „ještě může změnit, protože je příliš obecné“, že File Writer i se svým synchronním potomkem budou možná přesunuti do File Systemu a že celá implementace bývá dost často velmi pofidérní.

Přesunutí FileWriteru jistou logiku má, a proto si ho popíšeme až v části o File System. – pozn.aut.

BlobBuilder

Minule jsme si ukázali, jak číst data z blobu, dnes si ukážeme, jak je tam zapsat. Nečekejte žádné POSIXové metody – BlobBuilder nabízí pouze jedinou metodu, a to „append“.

var bb = new BlobBuilder();
bb.append("Lorem ipsum");
...

A dál? No, po pravdě řečeno, moc toho není:

...
bb.append(" dolor sit amec");
...

Metoda append() přidává, jak už vás asi napadlo, data na konec budovaného blobu (souboru). Jako parametr může mít řetězec, ArrayBuffer (pole binárních dat) nebo jiný blob.

Pokud je parametrem řetězec, lze druhým parametrem předepsat, jak naložit s konci řádek – hodnota „transparent“ je předvybraná a znamená, že řetězec je uložen tak jak je, bez jakýchkoli změn. Hodnota „native“ by měla změnit konce řádek podle systému, na kterém běží. Celá tato funkcionalita je ale zpochybňována, resp. její užitečnost – jakékoli překódovávání by mělo být na autorovi aplikace, a ve specifikaci je teď poznámka: Co by se stalo, kdyby to tam nebylo?

Pomocí append() si tedy poskládáme data do blobu. Když je máme poskládaná, získáme celý vybudovaný blob metodou getBlob(). Jako nepovinný parametr můžeme této metodě předat řetězec, v němž bude MIME typ, který náš vygenerovaný blob má. 

...
var blob = bb.getBlob("text/plain");
...

A máme ho!

Polyfill: Pokud náš (váš, nebo jejich) prohlížeč BlobBuilder nemá, podstrčte mu BlobBuilder.js

.toBlob()

Některé API nabízejí i metodu toBlob(). Jako příklad si uvedeme canvas. Obrázek, vytvořený v canvasu, ať už je to jakýmkoli způsobem, můžeme převést na blob právě pomocí této metody. Metoda je asynchronní, takže jako první parametr očekává callback, kterému předá hotový blob. Druhý, volitelný, parametr je MIME typ dat – tedy například „ image/jpeg“. Přednastavená volba je „ image/png“. U možnosti „image/jpeg“ může programátor přidat i třetí parametr, a to číslo v rozsahu 0,0 – 1,0 včetně – jak vás jistě napadá, slouží k určení kvality obrázku.

Polyfill: Pro prohlížeče, které toBlob u canvasu neimplementují, můžete použít knihovnu canvas-toBlob.js.

FileSaver, FileSaverSync

Tato dvě rozhraní se postarají o uložení blobu (tedy binárních dat) do souboru na disk – samozřejmě neukládají nic na pozadí, ale hezky otevřou standardní dialog pro uložení souboru. Rozhraní FileSaver definuje sadu událostí, které můžete obsloužit (onwritestart, onprogress, onwriteend) a metodu abort(). Rozhraní FileSaverSync nabízí metodu saveAs(), která je globálně dostupná v objektu window (resp. WebWorker), a její použití je opravdu prosté:

...
var fileSaver = window.saveAs(blob, "test_file");

Po jejím zavolání prohlížeč začne ukládat soubor (počká předtím ještě na výsledek ukládacího dialogu, samozřejmě). Nevýhodou je, že celou tu dobu vykonávání skriptů stojí.

Návrat do reality…

Autor článku používá relativně nové prohlížeče – FF6 a Chrome 13. Napsal si proto jednoduchý testovací skript:

var bb = new BlobBuilder();
bb.append("Lorem ipsum");
var blob = bb.getBlob();

var fs = new FileSaver(blob);

a čekal, co se stane. Nestalo se nic – oba prohlížeče oznámily, že neznají BlobBuilder. Dobrá tedy…

var BlobBuilder = BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder;

Teď už vytvoření blobu prošlo bez problémů. Další překážku představoval FileSaver. „Nedefinovaný objekt“. Mnoho tutoriálů vůbec s FileSaverem nepracuje, volají rovnou metodu window.saveAs(). Dobrá tedy:

var fs = saveAs(blob, "test_file");

Výsledek? Samosebou: nedefinované saveAs. Pomohl polyfill FileSaver.js.

Realita je tedy dnes, v září 2011, taková, že tyto metody jsou ve specifikaci stále ještě v rozpracovaném stavu, neustálené, a pokud je chcete použít, nezbývá, než využít zmíněné polyfills.

Možnosti těchto rozhraní pěkně demonstruje příklad.

ObjectURL

Pokud jste si zkusili příklad v prohlížeči Chrome s verzí nižší než 14, možná vás zarazil prapodivný název souboru v dialogovém okně, který vypadá jako nějaké UUID. Nejste daleko od pravdy – opravdu jde o UUID, respektive o identifikátor pro ObjectURL.

ObjectURL by šlo nejpřesněji popsat jako „handler ID pro objekty typu Soubor“. Je podobné již zmiňovaným DataURL. Jen místo celého obsahu souboru v kódování Base64, což může být nepraktické, obsahují pouze identifikátor daného souboru v prohlížeči – ono UUID. Objektovou URL (má podobu např. blob:250e8200-df9b-aed4-aa16-446655440000) můžeme použít jako svého druhu zástupce pro celý soubor. Pokud budeme takovou adresu vkládat do DOM, například jako hodnotu atrributu SRC u elementu IMG, jistě to bude pohodlnější než manipulovat obří mnohasetkilobaj­trovou datovou URL.

Jak objectURL získat? Slouží k tomu metoda window.URL.createObjectURL(), jejímž parametrem je blob/soubor, pro nějž chcete takovou URL získat. Nezaapomeňme, že tato URL platí jen pro aktuální sezení a pouze pro daný prohlížeč – nemá smysl jej posílat na server nebo s ním jakkoli pracovat mimo kontext aktuálníhop prohlížeče; bylo by to podobné jako distribuovat zástupce.

Opačnou funkci nabízí window.URL.revokeObjectURL(). Když už není ObjectURL dále potřeba, lze jej touto metodou „zneplatnit“.

Souhrn

Specifikace pro práci se soubory, konkrétně jejich vytváření a ukládání existují, ovšem stav jejich současné implementace je poměrně tristní. Jejich nasazení v současnosti umožňují pouze hacky a polyfill knihovny, proto je lze doporučit pouze pro doplňkové funkce; vystavět na nich nějaký podstatný pilíř své aplikace bude minimálně několik let čistý hazard.

Užitečné odkazy

Komentáře

Subscribe
Upozornit na
guest
0 Komentářů
Inline Feedbacks
View all comments

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.