API FileReader HTML5 umožňuje klientskému prohlížeči číst lokální soubory uživatele, takže nahraný soubor již není čten serverem, což výrazně snižuje zátěž serveru a šetří čas potřebný k nahrání souboru. V praxi jsem však zjistil, že s FileReader.readAsText() snadno zvládnu 300k log soubor, ale když je log velký jako 1G nebo dokonce 2G, prohlížeč spadne. Je to proto, že readAsText() načte cílový soubor do paměti najednou, což způsobí, že paměť překročí limit. Pokud webová aplikace často potřebuje zpracovávat velké soubory, měli bychom použít FileReader.readAsArrayBuffer() k jejich čtení po částech.
Testovací scénář
Náš scénář je jednoduchý, tedy použít JavaScript k získání časového rozsahu IIS logu
Ukázkové záznamy IIS:
#Software: Microsoft Internet Information Services 10.0 #Version: 1.0 #Date: 2016-08-18 06:53:55 #Fields: čas s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken 2016-08-18 06:53:55 ::1 GET / - 80 - ::1 Mozilla/5.0+(Windows+NT+10.0; +WOW64; +Trident/7,0; +rv:11.0)+like+Gecko - 200 0 0 476 2016-08-18 06:53:55 ::1 GET /iisstart.png - 80 - ::1 Mozilla/5.0+(Windows+NT+10.0; +WOW64; +Trident/7,0; +rv:11.0)+like+Gecko http://localhost/ 200 0 0 3 2016-08-18 08:45:34 10.172.19.198 GET /test/pac/wpad.dat - 80 - 10.157.21.235 Mozilla/5.0+(Windows+NT+6.1; +Win64; +x64; +Trident/7,0; +rv:11.0)+like+Gecko - 404 3 50 265 2016-08-18 08:46:44 10.172.19.198 GET /test/pac/wpad.dat - 80 - 10.157.21.235 Mozilla/5.0+(Windows+NT+6.1; +Win64; +x64; +Trident/7,0; +rv:11.0)+like+Gecko - 200 0 0 6 Naším cílem je získat časový rámec tohoto logu:
Začátek: 2016-08-18 06:53:55 Konec studia: 2016-08-18 08:46:44
Použijte implementaci readAsText()
Použití readAsText() je relativně jednoduché, po získání řetězce celého souboru získáte prvních 19 znaků každého řádku od začátku, určíte, zda je splněn formát data, pokud je splněn, těchto 19 znaků je čas začátku, a totéž se projde každou řádkou od konce, aby se získal čas konce, kód je následující:
Výsledky vzorku IIS logu (velikost: 1k) jsou přesně podle očekávání.
Ale jakmile si vyberemeVětší IIS log (velikost: 2G) a prohlížeč spadne。 Důvodem je, že readAsText() nejprve načte celý soubor do paměti, takže pokud je soubor příliš velký, nebude dostatek paměti a proces prohlížeče spadne.
Použijte implementaci readAsArrayBuffer()
Protože objekt File v JavaScriptu dědí z Blob, můžeme použít metodu Blob.slice() k rozdělení souboru na malé části, takže obecná myšlenka je:
Nejprve vezměte prvních 10 000 obsahu souboru a převeďte ho na text Vezměte prvních 19 znaků každého řádku od začátku, abyste zjistili, zda je datum splněno, a pokud ano, těchto 19 znaků je čas začátku Pak vezmi 10k obsahu na konci souboru a převed ho na text Podobně projděte každou čáru od obsahu ocasu, abyste získali čas konce
Kód je následující:
Pomocí readAsArrayBuffer() jsme dokázali získat požadované výsledky ve velmi krátkém čase, i s více než 2G IIS logy.
|