function handleFileSelect(event) { let { files } = event.target; if (!files.length) { return; } const handleLoadStart = (ev, file) => console.log(`>>> Start load ${file.name}`); const handleProgress = (ev, file) => { if (!ev.lengthComputable) { return; } // 计算进度,并且以百分比形式展示 const percent = Math.round((ev.loaded / ev.total) * 100); console.log(`<<< Loding ${file.name}, progress is ${percent}%`); }; for (let file of files) { const reader = new FileReader(); reader.onloadstart = ev => handleLoadStart(ev, file); reader.onprogress = ev => handleProgress(ev, file); reader.readAsArrayBuffer(file); }}document .querySelector("#files") .addEventListener("change", handleFileSelect, false);
文章插图
slice
大文件分片读取在对于超大文件,一般采用分片上传的思路解决 。文章开头有讲到,File 是 Blob 的一个特例 。而 Blob 上有一个 slice (https://developer.mozilla.org/zh-CN/docs/Web/API/Blob/slice)方法,通过它,前端就可以实现分片读取大文件的操作 。
为了方便说明,请先准备好一个 txt 文件,文件内容就是:hello world 。
示例代码如下,代码中只读取前 5 个字节,由于每个英文字母占 1 个字节,所以打印结果应该是“hello” 。
function handleFileSelect(event) { let { files } = event.target; if (!files.length) { return; } // 为了方便说明,这里仅仅读取第一个文件 const file = files[0]; // 读取前5个字节的内容 const blob = file.slice(0, 5); const reader = new FileReader(); // 控制台输出结果应该是:hello reader.onload = ev => console.log(ev.target.result); reader.readAsText(blob);}document .querySelector("#files") .addEventListener("change", handleFileSelect, false);拖拽上传和前面所述的 File API 相关是完全一样的 。唯一需要特殊处理的是文件对象的获取入口改变了 。对于 <input> 标签,监听 onchange 事件,FileList 存放在 event.target.files 中;对于拖拽操作,FileList 存放在拖拽事件的回调函数参数里,通过 event.dataTransfer.files 访问即可 。
需要修改一下 html 代码:
<!DOCTYPE html><head> <meta charset="UTF-8"> <style> #container { width: 300px; height: 300px; border: 3px dotted red; } </style></head><body> <div id="container"></div> <script src=https://www.isolves.com/it/cxkf/yy/html5/2019-07-23/"./script.js">