API FileReader HTML5 umožňuje klientskému prehliadaču čítať lokálne súbory používateľa, takže nahraný súbor už server nečíta, čo výrazne znižuje záťaž servera a šetrí čas potrebný na nahranie súboru. V praxi som však zistil, že s FileReader.readAsText() ľahko zvládnem 300k log súbor, ale keď je log veľký ako 1G alebo dokonca 2G, prehliadač spadne. Je to preto, že readAsText() načíta cieľový súbor do pamäte naraz, čo spôsobí, že pamäť prekročí limit. Ak webová aplikácia často potrebuje spracovávať veľké súbory, mali by sme použiť FileReader.readAsArrayBuffer() na čítanie súborov po častiach.
Testovací scenár
Náš scenár je jednoduchý, teda použiť JavaScript na získanie časového rozsahu IIS logu
Ukážkové záznamy IIS:
#Software: Microsoft Internet Information Services 10.0 #Version: 1.0 #Date: 2016-08-18 06:53:55 #Fields: dátum č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 cieľom je získať časový rámec toho logu:
Začiatok: 2016-08-18 06:53:55 Koniec: 2016-08-18 08:46:44
Použite implementáciu readAsText()
Použitie readAsText() je relatívne jednoduché – po získaní reťazca celého súboru získate prvých 19 znakov každého riadku od začiatku, zistite, či je dátumový formát splnený, ak je splnený, týchto 19 znakov je čas začiatku a rovnaký postup prechádza každým riadkom od konca na dosiahnutie konca kódu, kód je nasledovný:
Bežné výsledky vzorového IIS logu (veľkosť: 1k) sú presne také, ako sme očakávali.
Ale keď si vyberiemeVäčší IIS log (veľkosť: 2G) a prehliadač padá。 Dôvodom je, že readAsText() najskôr načíta celý súbor do pamäte, takže ak je súbor príliš veľký, nebude dostatok pamäte a proces prehliadača spadne.
Použite implementáciu readAsArrayBuffer()
Keďže objekt File v JavaScripte dedí z Blob, môžeme použiť metódu Blob.slice() na rozdelenie súboru na malé časti, základná myšlienka je:
Najprv vezmite prvých 10 000 obsahu súboru a prekonvertujte ho na text Vezmite prvých 19 znakov každého riadku od začiatku, aby ste zistili, či je dátumový formát splnený, a ak áno, týchto 19 znakov je čas začiatku Potom vezmi 10k obsah na konci súboru a prekonvertuj ho na text Podobne prejdite každý riadok od obsahu chvosta, aby ste získali koncový čas
Kód je nasledovný:
Pomocou readAsArrayBuffer() sme dokázali dosiahnuť požadované výsledky vo veľmi krátkom čase, aj s viac ako 2G IIS logami.
|