File va FileReader
Foydalanuvchi kompyuteridagi faylni brauzerga yuklaganida (masalan <input type="file"> orqali), biz File obyektini olamiz. File โ bu Blobning kengaytirilgan ko'rinishi bo'lib, unga fayl nomi va o'zgartirilgan sanasi qo'shilgan. Fayl mazmunini o'qish uchun esa FileReader ishlatiladi. Bularning barchasi brauzerga xos, shuning uchun quyidagi misollar brauzer muhitiga oid.
File obyekti
File โ Blobdan meros oladi, shuning uchun uning barcha xususiyatlari (size, type, slice) mavjud, plyus qo'shimchalari:
nameโ fayl nomi (masalanrasm.png);lastModifiedโ oxirgi o'zgartirilgan vaqt (timestamp, millisekundlarda);sizeโ fayl hajmi baytlarda (Blobdan meros);typeโ MIME turi (Blobdan meros).
File obyektini konstruktor orqali ham yasash mumkin, lekin amaliyotda ko'proq foydalanuvchi tanlovi orqali olinadi:
// File ni to'g'ridan-to'g'ri yaratish (kam ishlatiladi)
let file = new File(["salom"], "hello.txt", {
type: "text/plain",
lastModified: Date.now()
});
console.log(file.name); // hello.txt
console.log(file.size); // 5
console.log(file.type); // text/plain
input.files orqali fayl olish
Amaliyotda File obyektlari <input type="file"> elementidan olinadi. Foydalanuvchi fayl tanlagach, input.files โ FileList (fayllar ro'yxati) to'ldiriladi:
// HTML: <input type="file" id="tanlov" multiple>
let input = document.getElementById("tanlov");
input.addEventListener("change", function() {
let files = input.files; // FileList
console.log("Tanlangan fayllar: " + files.length);
for (let file of files) {
console.log(file.name + " - " + file.size + " bayt");
}
});
multiple atributi bir nechta fayl tanlashga imkon beradi. files โ FileList obyekti, u massivga o'xshaydi (indeks va length bor), lekin toza massiv emas. Kerak bo'lsa Array.from(files) bilan massivga o'giring.drop hodisasida event.dataTransfer.files ham FileList qaytaradi โ xuddi input.filesdek ishlaydi.FileReader: faylni o'qish
File (yoki Blob) mazmunini o'qish uchun FileReader ishlatiladi. Bu โ asinxron obyekt bo'lib, faylni o'qib bo'lgach hodisa (event) chaqiradi:
let reader = new FileReader();
FileReaderning o'qish metodlari fayl mazmunini turli formatda beradi:
readAsText(file, [encoding])โ faylni matn (satr) sifatida o'qiydi (standart UTF-8);readAsArrayBuffer(file)โ faylni ikkilikArrayBuffersifatida o'qiydi;readAsDataURL(file)โ faylni base64data:URL sifatida o'qiydi;readAsBinaryString(file)โ har bir baytni belgi sifatida o'qiydi (eskirgan, ishlatmang).
O'qish asinxron bo'lgani uchun natija to'g'ridan-to'g'ri qaytarilmaydi โ u hodisalar orqali keladi:
loadโ o'qish muvaffaqiyatli tugadi; natijareader.resultda;errorโ o'qishda xatolik; sababreader.errorda;progressโ o'qish davomida vaqti-vaqti bilan chaqiriladi;loadendโ o'qish tugadi (muvaffaqiyat yoki xatolikdan qat'i nazar).
readAsText: matnli faylni o'qish
Matnli faylni o'qishning to'liq misoli:
let input = document.getElementById("tanlov");
input.addEventListener("change", function() {
let file = input.files[0];
let reader = new FileReader();
reader.onload = function() {
// o'qish tugadi, natija reader.result da
console.log(reader.result);
};
reader.onerror = function() {
console.log("Xatolik: " + reader.error);
};
reader.readAsText(file); // o'qishni boshlaymiz
});
readAsText (va boshqa readAs...) metodlari darhol natija qaytarmaydi. Ular o'qishni boshlaydi va tugagach onloadni chaqiradi. Natijaga onload ichida murojaat qiling โ readAsText chaqiruvidan keyin darhol reader.result hali null bo'ladi.readAsDataURL: rasmni ko'rsatish
readAsDataURL faylni data: URL (base64) ko'rinishida beradi. Bu, ayniqsa, tanlangan rasmni yuklashdan oldin oldindan ko'rsatish (preview) uchun qulay:
let input = document.getElementById("rasmTanlov");
input.addEventListener("change", function() {
let file = input.files[0];
let reader = new FileReader();
reader.onload = function() {
// natija: data:image/png;base64,iVBORw0KGgo...
let img = document.createElement("img");
img.src = reader.result;
document.body.appendChild(img);
};
reader.readAsDataURL(file);
});
data: URL rasmni to'liq base64 satr sifatida saqlaydi โ serverga murojaat qilmaydi. Kichik rasmlar uchun qulay, lekin base64 ma'lumot hajmini ~33% oshiradi. Katta fayllar uchun URL.createObjectURL(file) tejamkorroq (u ham to'g'ridan-to'g'ri File bilan ishlaydi).readAsArrayBuffer: ikkilik o'qish
Fayl baytlarini past darajada qayta ishlash kerak bo'lsa (masalan, fayl formatini tahlil qilish, sarlavhani o'qish), readAsArrayBuffer ishlatiladi:
let file = input.files[0];
let reader = new FileReader();
reader.onload = function() {
let buffer = reader.result; // ArrayBuffer
let bytes = new Uint8Array(buffer);
// masalan, PNG sarlavhasini tekshiramiz
// PNG fayllari 0x89 0x50 0x4E 0x47 bilan boshlanadi
let isPng = bytes[0] === 0x89 &&
bytes[1] === 0x50 &&
bytes[2] === 0x4E &&
bytes[3] === 0x47;
console.log("PNG fayli: " + isPng);
};
reader.readAsArrayBuffer(file);
file.slice(0, 100) bilan bo'lak oling, so'ng shu Blobni readAsArrayBufferga bering. Butun faylni o'qish shart emas โ bu tezroq va xotira tejaydi.Yuklash jarayonini kuzatish (progress)
Katta faylni o'qiganda foydalanuvchiga jarayon foizini ko'rsatish uchun progress hodisasi ishlatiladi. Uning obyektida loaded (o'qilgan baytlar) va total (jami baytlar) bor:
let reader = new FileReader();
reader.onprogress = function(event) {
if (event.lengthComputable) {
let foiz = Math.round((event.loaded / event.total) * 100);
console.log("O'qildi: " + foiz + "%");
}
};
reader.onload = function() {
console.log("Tugadi!");
};
reader.readAsArrayBuffer(file);
event.lengthComputable โ jami hajm oldindan ma'lummi degan bayroq. Agar u false bo'lsa, foizni hisoblab bo'lmaydi (total noaniq). Lokal fayllar uchun odatda true bo'ladi.O'qishni to'xtatish
Boshlangan o'qishni reader.abort() bilan bekor qilish mumkin. Bu, masalan, foydalanuvchi katta faylni tanlab, so'ng fikridan qaytganda kerak bo'ladi:
let reader = new FileReader();
reader.readAsArrayBuffer(katta_fayl);
// keyinroq, kerak bo'lmay qolsa:
reader.abort(); // o'qishni to'xtatamiz
reader.onabort = function() {
console.log("O'qish bekor qilindi");
};
FileReader va Blob
FileReader nafaqat File, balki har qanday Blobni o'qiy oladi โ chunki File Blobdan meros oladi. Shuning uchun fetchdan kelgan Blobni ham FileReader bilan o'qish mumkin. Lekin zamonaviy kodda Blobning o'z await blob.text() / await blob.arrayBuffer() metodlari qulayroq โ ular Promise qaytaradi va async/await bilan toza yoziladi.
await file.text() yoki await file.arrayBuffer() yetarli โ FileReader shart emas. FileReader esa progress hodisasi kerak bo'lganda yoki eski brauzerlarni qo'llab-quvvatlashda foydali bo'lib qoladi.Xulosa
FileโBlobning kengaytmasi; qo'shimchanamevalastModifiedxususiyatlari bor;- Fayllar
input.files(FileList) yoki drag-and-drop orqali olinadi; FileReaderโ faylni asinxron o'qiydi; natija hodisalar orqali keladi;readAsText,readAsDataURL,readAsArrayBufferโ turli formatlarda o'qish;- Natija
reader.resultda, faqatonloadishlagach mavjud bo'ladi; progresshodisasi bilan yuklash foizini kuzatish,abort()bilan to'xtatish mumkin;- Zamonaviy kodda ko'pincha
await file.text()/file.arrayBuffer()yetarli.