API-ul FileReader al HTML5 permite browserului client să citească fișierele locale ale utilizatorului, astfel încât fișierul încărcat să nu mai fie citit de server, ceea ce reduce semnificativ povara asupra serverului și economisește timpul necesar pentru încărcarea fișierului. Totuși, în practică, am descoperit că pot gestiona ușor un fișier de log de 300k cu FileReader.readAsText(), dar când fișierul de log este de dimensiunea de 1G sau chiar 2G, browserul se blochează. Acest lucru se datorează faptului că readAsText() va încărca fișierul țintă în memorie deodată, determinând ca memoria să depășească limita. Așadar, dacă aplicația web trebuie adesea să proceseze fișiere mari, ar trebui să folosim FileReader.readAsArrayBuffer() pentru a citi fișierele bucată cu bucată.
Scenariu de test
Scenariul nostru este simplu, și anume să folosim JavaScript pentru a obține intervalul de timp al unui jurnal IIS
Exemplu de jurnale IIS:
#Software: Microsoft Internet Information Services 10.0 #Version: 1.0 #Date: 2016-08-18 06:53:55 #Fields: dată timp 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 Scopul nostru este să obținem intervalul de timp al acelui jurnal:
Ora de începere: 2016-08-18 06:53:55 Ora de sfârșit: 2016-08-18 08:46:44
Folosește implementarea readAsText()
Folosirea readAsText() este relativ simplă, după ce ai obținut șirul întregului fișier, iei primele 19 caractere ale fiecărei linii de la început, determini dacă formatul de dată este îndeplinit, dacă este satisfăcut, atunci aceste 19 caractere reprezintă ora de început, iar același lucru trece prin fiecare linie de la coadă pentru a obține ora de sfârșit, codul este următorul:
Rezultatele rulante ale eșantionului jurnal IIS (dimensiune: 1k) sunt așa cum ne așteptam.
Dar odată ce alegemUn jurnal IIS mai mare (dimensiune: 2G) și browserul se prăbușește。 Motivul este că readAsText() va încărca mai întâi întregul fișier în memorie, deci dacă fișierul este prea mare, nu va exista suficientă memorie și procesul din browser se va bloca.
Folosește implementarea readAsArrayBuffer()
Deoarece obiectul File în JavaScript moștenește din Blob, putem folosi metoda Blob.slice() pentru a tăia fișierul în bucăți mici, ideea generală este:
Mai întâi, ia primele 10.000 de conținut ale fișierului și convertește-le în text Ia primele 19 caractere ale fiecărei linii de la început pentru a determina dacă formatul de dată este îndeplinit, iar dacă da, aceste 19 caractere reprezintă ora de început Apoi ia conținutul de 10k de la finalul fișierului și convertește-l în text În mod similar, parcurge fiecare linie de la conținutul cozii pentru a obține ora finală
Codul este următorul:
Folosind readAsArrayBuffer(), am reușit să obținem rezultatele dorite într-un timp foarte scurt, chiar și cu mai mult de 2G loguri IIS.
|