FileReader API на HTML5 позволява на клиентския браузър да чете локалните файлове на потребителя, така че каченият файл вече не се чете от сървъра, което значително намалява натоварването върху сървъра и спестява времето, необходимо за качване на файла. Въпреки това, на практика установих, че лесно мога да обработя лог файл от 300k с FileReader.readAsText(), но когато лог файлът е толкова голям колкото 1G или дори 2G, браузърът се срива. Това е така, защото readAsText() зарежда целевия файл в паметта наведнъж, което води до надвишаване на лимита. Така че, ако уеб приложението често трябва да обработва големи файлове, трябва да използваме FileReader.readAsArrayBuffer(), за да четем файловете парче по парче.
Тестов сценарий
Нашият сценарий е прост – да използваме JavaScript, за да получим времевия диапазон на IIS лог
Примерни IIS логове:
#Software: Microsoft Internet Information Services 10.0 #Version: 1.0 #Date: 2016-08-18 06:53:55 #Fields: date time 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; +Тризъбец/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; +Тризъбец/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; +Тризъбец/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; +Тризъбец/7.0; +rv:11.0)+like+Gecko - 200 0 0 6 Нашата цел е да получим времевия диапазон на този дневник:
Начало: 2016-08-18 06:53:55 Край: 2016-08-18 08:46:44
Използвайте имплементацията readAsText()
Използването на readAsText() е сравнително просто: след като получите низа на целия файл, вземете първите 19 знака от всеки ред от началото, определите дали форматът на дата е изпълнен, ако е удовлетворен, тези 19 знака са началният час, и същото преминава през всеки ред от опашката, за да се получи крайното време, кодът е следният:
Текущите резултати на примерния IIS лог (размер: 1k) са както очаквахме.
Но щом изберемПо-голям IIS лог (размер: 2G) и браузърът се срива。 Причината е, че readAsText() първо зарежда целия файл в паметта, така че ако файлът е твърде голям, няма да има достатъчно памет и процесът на браузъра ще се срине.
Използвайте реализацията readAsArrayBuffer()
Тъй като обектът File в JavaScript наследява от Blob, можем да използваме метода Blob.slice(), за да разрежем файла на малки части, общата идея е:
Първо, вземете първите 10k съдържание на файла и ги конвертирайте в текст Вземете първите 19 знака от всеки ред от началото, за да определите дали форматът на дата е изпълнен, и ако да, тези 19 знака са началният час След това вземете съдържанието от 10k в края на файла и го конвертирайте в текст По същия начин преминете през всяка линия от съдържанието на опашката, за да получите крайното време
Кодът е следният:
Използвайки readAsArrayBuffer(), успяхме да получим желаните резултати за много кратко време, дори с повече от 2G IIS логове.
|