API FileReader HTML5 memungkinkan browser klien untuk membaca file lokal pengguna, sehingga file yang diunggah tidak lagi dibaca oleh server, yang sangat mengurangi beban pada server dan menghemat waktu yang diperlukan untuk mengunggah file. Namun, dalam praktiknya, saya menemukan bahwa saya dapat dengan mudah menangani file log 300k dengan FileReader.readAsText(), tetapi ketika file log sebesar 1G atau bahkan 2G, browser akan mogok. Ini karena readAsText() akan memuat file target ke dalam memori sekaligus, menyebabkan memori melebihi batas. Jadi jika aplikasi web sering perlu memproses file besar, kita harus menggunakan FileReader.readAsArrayBuffer() untuk membaca file sepotong demi sepotong.
Skenario pengujian
Skenario kami sederhana, yaitu menggunakan JavaScript untuk mendapatkan rentang waktu log IIS
Contoh log IIS:
#Software: Layanan Informasi Internet Microsoft 10.0 #Version: 1.0 #Date: 2016-08-18 06:53:55 #Fields: tanggal waktu 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 DAPATKAN / - 80 - ::1 Mozilla/5.0+(Windows+NT+10.0; +WOW64; + Trisula/7.0; +rv:11.0)+suka+tokek - 200 0 0 476 2016-08-18 06:53:55 ::1 DAPATKAN /iisstart.png - 80 - ::1 Mozilla/5.0+(Windows+NT+10.0; +WOW64; + Trisula/7.0; +rv:11.0)+suka+Tokek http://localhost/ 200 0 0 3 2016-08-18 08:45:34 10.172.19.198 DAPATKAN /test/pac/wpad.dat - 80 - 10.157.21.235 Mozilla/5.0+(Windows+NT+6.1; +Menang64; +x64; + Trisula/7.0; +rv:11.0)+suka+tokek - 404 3 50 265 2016-08-18 08:46:44 10.172.19.198 DAPATKAN /test/pac/wpad.dat - 80 - 10.157.21.235 Mozilla/5.0+(Windows+NT+6.1; +Menang64; +x64; + Trisula/7.0; +rv:11.0)+suka+tokek - 200 0 0 6 Tujuan kami adalah untuk mendapatkan kerangka waktu log itu:
Waktu mulai: 2016-08-18 06:53:55 Waktu berakhir: 2016-08-18 08:46:44
Menggunakan implementasi readAsText()
Menggunakan readAsText() relatif sederhana, setelah mendapatkan string dari seluruh file, dapatkan 19 karakter pertama dari setiap baris dari awal, tentukan apakah format tanggal terpenuhi, jika terpenuhi, maka 19 karakter ini adalah waktu mulai, dan hal yang sama berlaku melalui setiap baris dari ekor untuk mendapatkan waktu akhir, kodenya adalah sebagai berikut:
Hasil berjalan dari log IIS sampel (ukuran: 1k) seperti yang kami harapkan.
Tapi begitu kita memilihLog IIS yang lebih besar (ukuran: 2G) dan browser mogok。 Pasalnya, readAsText() akan memuat seluruh file ke dalam memori terlebih dahulu, jadi jika file terlalu besar, tidak akan ada cukup memori dan proses browser akan mogok.
Gunakan implementasi readAsArrayBuffer()
Karena objek File di JavaScript mewarisi dari Blob, kita dapat menggunakan metode Blob.slice() untuk memotong file menjadi potongan-potongan kecil, ide umumnya adalah:
Pertama, ambil 10k konten pertama dari file dan konversikan menjadi teks Ambil 19 karakter pertama dari setiap baris dari awal untuk menentukan apakah format tanggal terpenuhi, dan jika demikian, 19 karakter ini adalah waktu mulai Kemudian ambil konten 10k di akhir file dan ubah menjadi teks Demikian pula, lintasan setiap baris dari konten ekor untuk mendapatkan waktu akhir
Kodenya adalah sebagai berikut:
Dengan menggunakan readAsArrayBuffer(), kami bisa mendapatkan hasil yang kami inginkan dalam waktu yang sangat singkat, bahkan dengan lebih dari log IIS 2G.
|