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

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.

Seriál: Webdesignérův průvodce po HTML5 (21 dílů)

  1. Webdesignérův průvodce po HTML5 – díl nultý 25.5.2010
  2. Webdesignérův průvodce po HTML5 – nová sémantika 1.6.2010
  3. Webdesignérův průvodce po HTML5 – nová sémantika II 8.6.2010
  4. Webdesignérův průvodce po HTML5 – pohyblivé obrázky 15.6.2010
  5. Webdesignérův průvodce po HTML5 – používáme pohyblivé obrázky 22.6.2010
  6. Webdesignérův průvodce po HTML5 – taháme data od návštěvníka 29.6.2010
  7. HTML5 Audio: rádio ve vašich stránkách 13.7.2010
  8. Webdesignérův průvodce po HTML5: Microdata 20.7.2010
  9. AppCache: webové aplikace i bez připojení 27.7.2010
  10. Webdesignérův průvodce po HTML5: WebStorage 3.8.2010
  11. Webdesignérův průvodce po HTML5: Multithreading s WebWorkers 10.8.2010
  12. Webdesignérův průvodce po HTML5: Databáze v prohlížečích 17.8.2010
  13. Webdesignérův průvodce po HTML5: Shrnutí a rozhrnutí 24.8.2010
  14. HTML5: ukládáme si data k elementům 6.12.2010
  15. Webdesignérův průvodce po HTML5: Táhni a srůstej 5.1.2011
  16. HTML5: První krůčky s FileSystem API 15.2.2011
  17. Mobilizujeme web v HTML5 4.4.2011
  18. Single Page Apps a řešení problémů s historií 1.6.2011
  19. Page Visibility API: Kouká na mě vůbec někdo? 10.8.2011
  20. Práce se soubory v prohlížeči, díl 1 15.8.2011
  21. Práce se soubory v prohlížeči, díl 2 5.9.2011

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

Začal programovat v roce 1984 s programovatelnou kalkulačkou. Pokračoval k BASICu, assembleru Z80, Forthu, Pascalu, Céčku, dalším assemblerům, před časem v PHP a teď by rád neprogramoval a radši se věnoval starým počítačům.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Zatím nebyl přidán žádný komentář, buďte první!

Přidat komentář
Zdroj: https://www.zdrojak.cz/?p=3539