兼容性检查

if (window.File && window.FileReader && window.FileList && window.Blob) {//支持File APIs
} else {//不支持File APIs
}
复制代码

FileReader()

FileReader对象让web应用程序可以异步地读取存储在用户电脑上的文件(或者原始数据缓冲区)的内容。在JavaScript中,FileReaderd对象通过传入两种相应的对象(File和Blob)来进行数据的读取,而且这个方法在Web Workers中也能使用。

FileReader 包括四个异步读取文件的选项:

  • FileReader.readAsBinaryString(Blob|File) - 返回值的result 属性将包含二进制字符串形式的file/blob 数据。每个字节均由一个 [0..255] 范围内的整数表示。
  • FileReader.readAsText(Blob|File, opt_encoding) - 返回值的result 属性将包含文本字符串形式的 file/blob 数据。该字符串在默认情况下采用“UTF-8”编码。使用可选编码参数可指定其他格式。
  • FileReader.readAsDataURL(Blob|File) - 返回值的result 属性将包含编码为数据网址的 file/blob 数据。
  • FileReader.readAsArrayBuffer(Blob|File) - 返回值的result 属性将包含 ArrayBuffer 对象形式的 file/blob 数据。

FileReader 对象调用其中某一种读取方法后,可使用 onloadstart、onprogress、onload、onabort、onerror 和 onloadend 跟踪其进度。

读取文件并显示进度

下面的示例从用户选择的内容中过滤掉了图片,对文件调用 reader.readAsDataURL(),并通过将“src”属性设为数据网址来呈现缩略图。

<style>.thumb {height: 75px;border: 1px solid #000;margin: 10px 5px 0 0;}#list {border: 1px solid lightgrey;padding: 15px;text-align: center;}#progress_bar {margin: 10px 0;padding: 3px;border: 1px solid #000;font-size: 14px;clear: both;opacity: 0;-moz-transition: opacity 1s linear;-o-transition: opacity 1s linear;-webkit-transition: opacity 1s linear;}#progress_bar.loading {opacity: 1.0;}#progress_bar .percent {background-color: #99ccff;height: auto;width: 0;}
</style><body><input type="file" name="files[]" id="files" multiple /><div id="list"></div><button onclick="abortRead();">Cancel read</button><script>let reader;let progress;let progress_bar;function abortRead() {reader.abort();}function errorHandler(evt) {let error = evt.target.error;switch (error.code) {case error.NOT_FOUND_ERR:alert('没有找到文件');break;case error.NOT_READABLE_ERR:alert('无法读取文件');break;case error.ABORT_ERR:break;default:alert('文件读取错误');}}function updateProgress(evt) {if (evt.lengthComputable) {let percentLoaded = Math.round((evt.loaded / evt.total) * 100);if (percentLoaded < 100) {progress.style.width = percentLoaded + '%';progress.textContent = percentLoaded + '%';}}}function handleFileSelect(evt) {let files = evt.target.files;//创建进度条progress_bar = document.createElement('div');progress_bar.id = 'progress_bar';progress = document.createElement('div');progress.className = 'percent';progress.style.width = '0%';progress.textContent = '0%';progress_bar.appendChild(progress);document.getElementById('list').appendChild(progress_bar);for (let i = 0; i < files.length; i++) {reader = new FileReader();if (!files[i].type.match('image.*')) {alert('选择的文件不是图片');abortRead();return;}reader.onerror = errorHandler;reader.onprogress = updateProgress;reader.onabort = (e) => {alert('文件读取已取消');};reader.onloadstart = (e) => {progress_bar.className = 'loading';};reader.onload = (e) => {let span = document.createElement('span');span.innerHTML = ['<img class="thumb" src="', e.target.result, '" title="', files[i].name, '"/>'].join('');document.getElementById('list').insertBefore(span, progress_bar);progress.style.width = '100%';progress.textContent = '100%';};reader.readAsDataURL(files[i]);}}document.getElementById('files').addEventListener('change', handleFileSelect, false);</script>
</body>
复制代码

See the Pen FileReader Demo by Lu (@smallbone) on CodePen.

FileList API

字面上可以理解为多个File对象组合成的数组,但是只有length属性item(index)方法,访问其中的File对象既可以使用files.item(index),也可以使用files[index]的方法。

File API

File对象是一种特定类型的Blob。FileReader, URL.createObjectURL(), createImageBitmap(), 以及XMLHttpRequest.send() 都接受Blobs和Files。

  • File对象包含的信息
{lastModified: 1428005315000,lastModifiedDate: Thu Apr 02 2015 15:08:35 GMT-0500 (CDT),name: "profile.pdf",size: 135568,type: "application/pdf",webkitRelativePath: ""
}
复制代码

需要注意的是,type是根据文件扩展名来判断的,所以并不是很可靠。根据上面File对象的信息其实就可以实现一些常用的功能了,比如限制文件上传的大小,初步的限制文件上传的类型(当然也可以通过input元素的accept属性来实现,但是最终的类型验证还是需要在服务器端实现)。

File对象一般通过以下途径返回的FileList对象获取:

  1. <input type="file">的元素
  2. 拖拽操作的DataTransfer对象
  3. 通过在一个HTMLCanvasElement上调用mozGetAsFile() API

通过input来选择文件

/* 假设input元素为<input type="file" id="upload" multiple> */
//multiple表示一次支持多个文件上传
let uploadInput = document.getElementById('upload');
uploadInput.addEventListener('change', ()=>{let fileList = uploadInput.files;console.log(fileList);
});
复制代码

由于FileList对象并没有forEach()方法,所以一般需要通过for循环来遍历其中的每个File对象:

for (var i = 0; fileCount = fileList.length; i < fileCount; i++) {console.log(fileList[i]);
}
复制代码

但是我们也可以通过其他方式来使用forEach()方法:

//1.call方法
[].forEach.call(fileList, (file, i, fileList)=>{...
});//2.ES6方法
Array.from(uploadInput).forEach((i)=>{...
});
复制代码

通过拖拽(drag&drop)选择文件

拖拽事件:

  • drag(开始拖动,持续事件)
  • dragend(释放鼠标或者按下ESC,结束拖动)
  • dragenter(进入有效的拖拽区域时)
  • dragexit(当一个元素不再是拖动操作的直接选择目标时)
  • dragleave(离开有效的拖拽区域时)
  • dragover(悬停在有效的拖拽区域内时,持续事件)
  • dragstart(开始拖动)
  • drop(目标放置到有效的拖拽区域时)

其中需要注意两点:

  1. 如果dragover事件不阻止默认事件,drop事件就不会被触发。
  2. dragexit和dragleave在不同浏览器中的触发存在差异,dragexit在Chrome浏览器中就永远不会被触发
//拖拽和显示区域
<div id="drop_zone">Drop files here</div>
<output id="list"></output><script>function handleFileSelect(evt) {evt.stopPropagation();evt.preventDefault();//注意这里不再是target.fileslet files = evt.dataTransfer.files;let output = [];[].forEach.call(files, (file)=>{output.push('<li><strong>', file.name, '</strong> (', file.type || 'n/a', ') - ', (file.size/1024).toFixed(3), ' Kb, last modified date: ', file.lastModifiedDate.toLocaleDateString(), '</li>');});document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>'; }function handleDragOver(evt) {evt.stopPropagation();evt.preventDefault();evt.dataTransfer.dropEffect = 'copy';}let dropZone = document.getElementById('drop_zone');dropZone.addEventListener('dragover', handleDragOver, false);dropZone.addEventListener('drop', handleFileSelect, false);
</script>
复制代码

如何使用File APIs来读取文件相关推荐

  1. input file读取文件

    js读取 input file 文件的两种方式: <div id="localImag"><img id="preview" src=&quo ...

  2. python 代码分块_[代码全屏查看]-python多进程分块读取文件

    [1].[代码] [Python]代码 # -*- coding: GBK -*- import urlparse import datetime import os from multiproces ...

  3. android 从assets和res中读取文件(转)

    1. 相关文件夹介绍 在Android项目文件夹里面,主要的资源文件是放在res文件夹里面的.assets文件夹是存放不进行编译加工的原生文件,即该文件夹里面的文件不会像xml,java文件被预编译, ...

  4. java file 字符串_Java读取一个文本文件拼接成一个字符串(readFileToString)

    import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.I ...

  5. java逐行读取文件内容执行sql语句_[11/100] 文件和异常

    最近学习效率很低,居然还开始熬夜玩耍了.好好干啊,技术差就要多付出啊. 操作模式 选择操作模式 读写文本文件 1.读取 import timedef main():f = Nonetry:# 一次性读 ...

  6. Android从assets和res中读取文件

    1. 相关文件夹介绍 在Android项目文件夹里面,主要的资源文件是放在res文件夹里面的.assets文件夹是存放不进行编译加工的原生文件,即该文件夹里面的文件不会像xml,java文件被预编译, ...

  7. scala 写入文件_Scala文件IO –写入文件,读取文件

    scala 写入文件 Today we will look into Scala File IO operations. File operations mainly include reading ...

  8. golang读取文件案例

    bufio.NewReader读入的是文件的缓存,利用缓存读入的文件可以缓慢输出. os.open传出的是两个数,一个是file是读取的文件,另外一个是err是文件的错误. str, err := r ...

  9. FileReader()读取文件

    FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据. 属性: FileReader.err ...

  10. php 读取文件自身内容,与读取文件输出内容

    一,读取文件 先解释一下,什么是读取文件本身,什么叫读取文件输入内容.举个例子test.php里面的内容<?php echo "test"; ?> 1,读取文件本身就是 ...

最新文章

  1. 编写工厂类和配置文件
  2. 1月末周中国五大顶级域名总量增3.4万 美国增3.3万
  3. 【功能升级】达摩盘3.0全新标签介绍前言
  4. 【做题记录】Codeforces做题记录
  5. 被丢弃的消息不能再次出现
  6. Python之XML解析详解
  7. 基于vue-cli的vuex配置
  8. python语音库_Python中的Python文本到语音
  9. 批量查看域用户登录计算机信息
  10. Sql中的触发器(Triggers)
  11. 上下协同,用友IPD的研发管理之道(下)
  12. [ExtJS] 颜色选择器2.0
  13. python求所有参数的乘积_python 通过可变参数计算n个数的乘积方法
  14. 直通车开通后没有展现量,启中教育来分析
  15. TCP连接建立三握手
  16. 大战谷歌!微软Bing引入ChatGPT;羊了个羊高·薪招纳技术人才;Debian彻底移除Python2;GitHub今日热榜 | ShowMeAI资讯日报
  17. serialize()序列化
  18. Mysql之浅析INSERT ON DUPLICATE
  19. Odata数据展示_SAP刘梦_新浪博客
  20. 新浪微博java开发_新浪微博API java开发

热门文章

  1. 洛谷 P1181数列分段SectionI 【贪心】
  2. 适配器模式/adapter模式/结构型模式
  3. 将 Entity Framework、LINQ 和 Model-First 用于 Oracle 数据库
  4. 双轴按键摇杆控制器控制TFTLCD(使用ADC1双通道DMA传输)
  5. SPOJ Pouring Water
  6. 在MyEclipse显示struts2源码和doc文档及自动完成功能
  7. Java的表达式和运算符
  8. 第四百零四天 how can I 坚持
  9. 【现代编译器】语法分析——正则表达式,上下文无关文法,递归下降分析,分析树...
  10. Delphi 中的DLL 封装和调用对象技术