FileReader详解

article/2025/11/5 7:59:14

我在Google Chrome Web Store上发布了一个案例hahaOCR,该扩展程序可以帮助用户识别出图片中的文字信息,并以文本形式显示,大家可以在chrome网上应用商店中找到我发布的应用程序,如图所示:

图1 - hahaOCR

该扩展程序支持用户通过文件上传按钮上传图片,请看演示效果:

图2 - 测试图片

图3 - 测试效果

接下来,我们将在本文中详细讲解该案例所涉及的文件(图片)处理模块。

参考资料

  1. MDN Web Docs:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader

1. FileReader概述

该对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用FileBlob对象指定要读取的文件或数据。其中File对象可以是来自用户在一个<input/>元素上选择文件后返回的FileList对象,也可以是来自拖拽操作生成的DataTransfer对象,还可以是来自一个HTMLCanvasElement上执行 mozGetAsFile()方法后返回的结果;Blob对象表示一个不可变、原始数据的类文件对象,它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream来用于数据操作,Blob表示的不一定是JavaScript原生格式的数据,File接口基于Blob,继承了Blob的功能并将其扩展使其支持用户系统上的文件。

2. FileReader属性

为了更加直观的解释FileReader的三个属性,我们来看一段简单的代码:

<input type="file" id="file" onchange="readFile(this.files[0])">
window.readFile = (file) => {console.log(file)console.log(file.type)var reader = new FileReader()console.log(reader)
}

上述代码中,我们定义了一个文件上传按钮,我们只对用户上传的第一个文件进行处理,当用户完成上传操作之后,我们来看一下控制台输出的信息:

图4 - FileReader属性

我们在上述代码中指定了三个console,第一个console输出了用户所上传文件的相关信息;第二个console输出了用户所上传文件的type;第三个console输出了FileReader实例的相关信息,请看解释:

  • FileReader.error(只读属性)
    该属性表示在读取文件时发生的错误,图1中显示error值为null,表示在读取用户所上传文件时没有出错。

  • FileReader.readyState(只读属性)
    该属性表示FileReader状态的数字,请看取值:

常量名描述
EMPTY0还没有加载任何数据
LOADING1数据正在被加载
DONE2已完成全部的读取请求

图1中显示readyState值为0,因为我们并没有加载任何数据,尽管我们完成了图片的上传,但我们并没有指定任何方法来读取该图片文件。

  • FileReader.result(只读属性)
    该属性表示文件的内容,仅在读取操作完成之后才有效,数据的格式取决于使用哪个方法来启动读取操作,图1中result值为null,因为我们并没有指定读取当前所上传文件的方法,接下来,我们通过FileReader.readAsDataURL()方法来读取一下该图片,请看代码:
window.readFile = (file) => {var reader = new FileReader()console.log(reader)reader.readAsDataURL(file)reader.onload = (res) => {console.log(res)}
}

请看控制台信息:

图5 - readAsDataURL方法

上述代码中,我们通过FileReader.readDataAsURL()方法读取用户所上传的图片文件,当读取完成后,其result属性中将包含一个data:URL格式的Base64字符串以表示所读取文件的内容,关于读取用户所上传文件的更多方法,请参考第三小节。

3. FileReader方法

接下来,我们来看一下FileReader接口的几个方法:

方法描述
FileReader.abort()终止读取操作,在返回时,该属性的值为DONE
FileReader.readAsArrayBuffer()开始读取指定的Blob中的内容,一旦完成,result属性中保存的是被读取文件的ArrayBuffer数据对象
FileReader.readAsBinaryString()开始读取指定的Blob中的内容,一旦完成,result属性中将包含所读取文件的原始二进制数据
FileReader.readAsDataURL()开始读取指定的Blob中的内容,一旦完成,result属性中将包含一个data:URL格式的Base64字符串以表示所读取文件的内容
FileReader.readAsText()开始读取指定的Blob中的内容,一旦完成,result属性中将包含一个字符串以表示所读取的文件内容

如上表所示,对于不同的文件我们可以采取不同的方法来完成读取操作,接下来,我们通过FileReader.readAsText()方法来读取一个文本,请看代码:

图6 - 文本内容
window.readFile = (file) => {var reader = new FileReader()console.log(reader)reader.readAsText(file)reader.onload = (res) => {console.log(res)}
}

请看演示效果:

图7 - readAsText方法

4. FileReader事件

我们继续来看FileReader接口的几个事件处理方法:

方法描述
FileReader.onabort()处理abort事件,该事件在读取操作被中断时触发
FileReader.onerror()处理error事件,该事件在读取操作发生错误时触发
FileReader.onload处理load事件,该事件在读取操作完成时触发
FileReader.onloadstart处理loadstart事件,该事件在读取操作开始时触发
FileReader.onloadend处理loadend事件,该事件在读取操作结束时(成功或失败)触发
FileReader.onprogress处理progress事件,该事件在读取Blob时触发

如上表所示,我们可以在用户上传文件的不同阶段指定不同的处理逻辑,请看代码:

<div class="example"><div class="file-select"><label for="avatar">Choose a profile picture:</label><input type="file"id="avatar" name="avatar"accept="image/png, image/jpeg"></div><img src="" class="preview" height="200" alt="Image preview..."><div class="event-log"><label>Event log:</label><textarea readonly class="event-log-contents" rows="20" cols="50"></textarea></div></div>

上述代码中,我们定义了一个文件上传按钮,具体来说是图片上传按钮;接着我们还定义了一个<img/>标签,其src属性值为空;最后,我们定义了一个文本输入框,用来显示不同事件处理程序读取图片文件的相关信息。

const fileInput = document.querySelector('input[type="file"]');
const preview = document.querySelector('img.preview');
const eventLog = document.querySelector('.event-log-contents');
const reader = new FileReader();function handleEvent(event) {console.log(event)eventLog.textContent = eventLog.textContent + `${event.type}: ${event.loaded} bytes transferred\n`;if (event.type === "load") {preview.src = reader.result;}
}function addListeners(reader) {reader.addEventListener('loadstart', handleEvent);reader.addEventListener('load', handleEvent);reader.addEventListener('loadend', handleEvent);reader.addEventListener('progress', handleEvent);reader.addEventListener('error', handleEvent);reader.addEventListener('abort', handleEvent);
}function handleSelected(e) {eventLog.textContent = '';const selectedFile = fileInput.files[0];if (selectedFile) {addListeners(reader);reader.readAsDataURL(selectedFile);}
}fileInput.addEventListener('change', handleSelected);

上述代码中,我们仅对用户上传的第一个图片文件进行处理(通过readAsDataURL方法读取);我们还通过EventTarget.addEventListener方法将FileReader指定的6种监听器(事件处理程序)注册到reader上;最后当触发load事件时,将读取成功之后的内容,即data:URL格式的Base64字符串赋值给空<img/>标签的src属性,并最终显示在页面中,请看演示效果:

图8 - FileReader事件处理程序演示

5. 案例实战

最后,我们来看一下本文最开始提到的hahaOCR案例中的文件处理模块,实现该逻辑功能的思路其实很简单:用户通过按钮或拖拽操作上传图片,上传成功之后调用接口将图片中的文字信息显示在<textarea/>中,接下来,我们来看一下实现该功能的代码:

//此处是手动选择文件
$('#input').change(function() {event.preventDefault();var filesToUpload = document.getElementById('input').files;var img_file = [];for (var i = 0; i < filesToUpload.length; i++) {var file = filesToUpload[i];if (/image\/\w+/.test(file.type) && file != "undefined") {img_file.push(file);}}var reader = new FileReader();var AllowImgFileSize = 2100000; //上传图片最大值(单位字节)( 2 M = 2097152 B )超过2M上传失败var imgUrlBase64;if (img_file) {//将文件以Data URL形式读入页面imgUrlBase64 = reader.readAsDataURL(file);reader.onload = function (e) {if (AllowImgFileSize != 0 && AllowImgFileSize < reader.result.length) {alert( '上传失败,请上传不大于2M的图片!');return;}else{$.ajax({type: 'post',url: '***', //这里是数据请求接口dataType: 'json',data: {"showapi_appid": '***', //这里需要改成自己的appid"showapi_sign": '***',  //这里需要改成自己的应用的密钥secret"base64":reader.result,},error: function(XmlHttpRequest, textStatus, errorThrown) {alert("操作失败!");},success: function(result) {var res = result.showapi_res_body.texts[0];console.log(res)$("#exampleFormControlTextarea1").val(res)}});}}}hahaOCR.prototype.getImageFile(img_file, filesToUpload.length);
});

上述代码中,我们限定了用户所上传图片文件的大小,并在文件上传成功时调用接口来对所上传的图片文件进行识别,识别成功之后,将图片中文字信息显示在<textarea/>中。

6. 文章最后

以上就是本文的所有内容,小伙伴们学会了嘛?快去实践一下吧!更多详情请关注我的更多开源作品:
1. 微信公众号(hahaCoder)

图9 - 微信公众号

2. 微信小程序(hahaAI)

图10 - 微信小程序

3. Github
链接地址:https://github.com/TURBO1002


http://chatgpt.dhexx.cn/article/Y49W1Rk0.shtml

相关文章

f.readlines()

f.readlines() ftext open(1299_wangyifei_edit.pinyin, r, encodingutf-8)lines ftext.readlines()print("lines",lines)l ftext.readlines()print("l",l)输出结果&#xff1a; 原因&#xff1a; readlines() 方法用于读取所有行(直到结束符 EOF)并返…

FileReader的用法

FileReader是一种异步文件读取机制&#xff0c;结合input:file可以很方便的读取本地文件。 input:file input的file类型会渲染为一个按钮和一段文字。点击按钮可打开文件选择窗口&#xff0c;文字表示对文件的描述&#xff08;大部分情况下为文件名&#xff09;&#xff1b;…

【原创】通过 ioctl + FIONREAD 判定数据可读

【原创】通过 ioctl FIONREAD 判定数据可读 摩云飞 2016-05-12 09:57:51 浏览470 评论0 libevent ioctl FIONREAD 摘要&#xff1a; 在排查业务 bug 的过程中&#xff0c;看到如下两种输出信息&#xff1a; TCP 连接正常情况下&#xff0c;进行数据读取 14:00:38 epoll_ctl…

fread函数详解

文章迁移&#xff1a; fread函数详解 - 码到城攻fread函数详解&#xff0c;C函数使用注意事项&#xff0c;freadhttps://www.codecomeon.com/posts/93/ 函数原型&#xff1a; size_t fread( void *buffer, size_t size, size_t count, FILE *stream ) buf…

SQLSTATE: Insert value list does not match column list: 1136 Column count doesn‘t match value count

使用thinkphp5的insertAll的批量新增函数&#xff0c;提示SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesnt match value count at row 2 其意思就是&#xff1a;在第二行数据开始&#xff0c;插入的&#xff0c;每行数据的值的个数和…

Column-Stores vs. Row-Stores: How Different Are They Really

概述 从论文的标题可以看出这篇论文不是陈述一种新的技术、架构&#xff0c;而更偏议论文一点&#xff0c;它主要的目的在于搞清楚对于分析类的查询为什么Column-Store比Row-Store好那么多&#xff1f;好在哪里&#xff1f;一般认为原因是: 分析类查询往往只查询一个表里面很少…

Android应用开发之( TableLayout中stretchColumns、shrinkColumns的用法)

从字面上来看&#xff0c;TableLayout也比较简单&#xff0c;关键是要对相关的属性要熟悉&#xff0c;先看一个简单的例子&#xff08;后面为效果图&#xff09;&#xff1a; <?xml version"1.0" encoding"utf-8"?> <TableLayout xmlns:android…

CollenctionList

1.Collection集合 1.1集合体系结构【记忆】 集合类的特点 提供一种存储空间可变的存储模型&#xff0c;存储的数据容量可以随时发生改变 集合类的体系图 1.2Collection集合概述和基本使用【应用】 Collection集合概述 是单例集合的顶层接口&#xff0c;它表示一组对象&#xff…

输入界面,关于stretchColumns和selectAllOnFocus的属性设置

这是整个TableLayout的代码&#xff1a; <TableLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:orientation"vertical"android:layout_width"fill_parent&qu…

android:stretchcolumns=0,1,2,3,stretch_stretch是什么意思

stretch是什么意思 stretch是伸展、可伸缩的意思。具体释义如下&#xff1a; stretch英 [stretʃ] 美 [strɛtʃ] 1、动词 v.伸展;延伸;持续;包括 例&#xff1a;It is better to stretch the tight muscles first 最好先伸展一下僵硬的肌肉。 2、名词 n.伸展;弹性;一片;一…

StretchBlt()函数使用

StretchBlt函数从源矩形中复制一个位图到目标矩形&#xff0c;必要时按目前目标设备设置的模式进行图像的拉伸或压缩。 说白了功能就是缩放。 函数原型如下 函数原型&#xff1a;BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeig…

STL_set/multiset

STL_set/multiset 简介&#xff1a;本文主要介绍STL中的&#xff0c;set与multiset的使用&#xff0c;只需要把本文的代码自己敲完便可学会。 set容器的基本概念 注意&#xff1a;set容器没有push_back, pop_back这两种插入接口&#xff0c;只能用insert函数进行插入 如果向s…

Column-Stores vs. Row-Stores: How Different Are They Really?

Column-Stores vs. Row-Stores: How Different Are They Really? 论文阐述的就是行存与列存 两者之间到底有什么区别 Abstract 论文首先给出结论&#xff1a;列式存储&#xff08;Column Stores&#xff09;比行式存储&#xff08;Row Stores&#xff09;在性能上好过一个数…

android:stretchcolumns=0,1,2,3,android:stretchColumns用法

TableLayout是一个使用复杂的布局&#xff0c;最简单的用法就仅仅是拖拉控件做出个界面&#xff0c;但实际上&#xff0c;会经常在代码里使用TableLayout&#xff0c;例如做出表格的效果。本文主要介绍TableLayout的基本使用方法。 < ?xml version"1.0" encoding…

cannot set a row with mismatched columns

错误&#xff1a;cannot set a row with mismatched columns 错误背景原错误情况错误原因解决方法 错误背景 在希望将dataframe a 中的特定行移至dataframe b 时出错&#xff0c;记录下自己使用的方法 原错误情况 #dataframe a 已知 a{ab:[1,2,3],bb:[3,4,5],cb:[4,5,6]} a …

TableLayout中stretchColumns、shrinkColumns的用法

android:stretchColumns"1" android:shrinkColumns"1"这两个属性是TableLayout所特有的&#xff0c;也是这两个属性影响了子对象的布局。 表格布局是按照行列来组织子视图的布局。表格布局包含一系列的Tabrow对象&#xff0c;用于定义行&#xff08;也可以…

TableLayout中stretchColumns和shrinkColumns使用

<?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:orientatio…

基于JAVA的即时通信软件

一.设计任务书 1.1 设计任务 本文设计的是一个简单的即时通信软件&#xff0c;利用 Java Socket 进行点到点通信&#xff0c;其工作机制模仿即时通信软件的基本功能&#xff0c;已实现的功能有&#xff1a; 客户端登录 客户端退出 群组成员之间传输文字或图片信息 该软件分为客…

一文教你用java实现即时通讯软件的设计

即时通讯软件即所谓的聊天工具&#xff0c;其主要用途是用于文字信息的传递与文件传输。使用eclipse作为即时通讯软件的开发工具&#xff0c;使用Socket建立通讯渠道&#xff0c;多线程实现多台计算机同时进行信息的传递&#xff0c;swing技术等进行实际开发相对比较合适。通过…

即时通讯软件七大优势详解

在以前&#xff0c;即时通讯软件被认为是一种专供个人使用的通信工具&#xff0c;随着社会的发展&#xff0c;各大商家企业开始慢慢接受这种通信工具并利用其协调公司内部沟通&#xff0c;从而满足公司的业务需求。那么即时通讯软件优势有哪些&#xff1f;为你细数它的七大优势…