Die FileReader-API von HTML5 ermöglicht es dem Client-Browser, die lokalen Dateien des Benutzers zu lesen, sodass die hochgeladene Datei nicht mehr vom Server gelesen wird, was die Belastung für den Server erheblich verringert und die Zeit spart, die für das Hochladen der Datei benötigt wird. In der Praxis habe ich jedoch festgestellt, dass ich eine 300k-Logdatei problemlos mit FileReader.readAsText() verarbeiten kann, aber wenn die Logdatei so groß wie 1G oder sogar 2G ist, stürzt der Browser ab. Dies liegt daran, dass readAsText() die Zieldatei auf einmal in den Speicher lädt, wodurch der Speicher das Limit überschreitet. Wenn die Webanwendung also oft große Dateien verarbeiten muss, sollten wir FileReader.readAsArrayBuffer() verwenden, um die Dateien Stück für Stück zu lesen.
Testszenario
Unser Szenario ist einfach: Wir verwenden JavaScript, um den Zeitbereich eines IIS-Protokolls zu erhalten.
Beispiel-IIS-Protokolle:
#Software: Microsoft Internet Information Services 10.0 #Version: 1,0 #Date: 18.08.2016 06:53:55 #Fields: Datum Zeit s-ip cs-methode cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status zeit-genommen 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 Unser Ziel ist es, den Zeitrahmen dieses Logbuchs zu erhalten:
Startzeit: 18.08.2016 06:53:55 Endzeit: 18.08.2016 08:46:44
Verwenden Sie readAsText()-Implementierung
Die Verwendung von readAsText() ist relativ einfach: Nachdem man die Zeichenkette der gesamten Datei erhalten hat, erhält man die ersten 19 Zeichen jeder Zeile von Anfang an, beurteilt, ob das Datumsformat erfüllt ist, falls es erfüllt ist, dann sind diese 19 Zeichen die Startzeit, und das gleiche gilt für jede Zeile vom Ende aus, um die Endzeit zu erhalten, der Code ist wie folgt:
Die laufenden Ergebnisse des IIS-Logbuchs der Stichprobe (Größe: 1k) sind wie erwartet.
Aber sobald wir wählenEin größeres IIS-Protokoll (Größe: 2G) und der Browser stürzt ab。 Der Grund ist, dass readAsText() die gesamte Datei zuerst in den Speicher lädt, sodass bei zu großer Dateigröße nicht genug Speicher vorhanden ist und der Browserprozess abstürzt.
Verwenden Sie readAsArrayBuffer()-Implementierung
Da das Dateiobjekt in JavaScript von Blob erbt, können wir die Blob.slice()-Methode verwenden, um die Datei in kleine Stücke zu schneiden; die Grundidee lautet:
Zuerst nehmen Sie die ersten 10.000 Inhalte der Datei und konvertieren Sie sie in Text Nehmen Sie die ersten 19 Zeichen jeder Zeile von Anfang an, um festzustellen, ob das Datumsformat erfüllt ist, und falls ja, sind diese 19 Zeichen die Startzeit Dann nimm den 10k-Inhalt am Ende der Datei und wandel ihn in Text um Ebenso durchquere jede Linie vom Schwanzinhalt aus, um die Endzeit zu erhalten
Der Code lautet wie folgt:
Mit readAsArrayBuffer() konnten wir die gewünschten Ergebnisse in sehr kurzer Zeit erzielen, selbst mit mehr als 2G IIS-Logs.
|