最近接手一个项目,接触了一些文件操作。所以这里总结一下日常使用的处理方法。让我们将其用作学习笔记。如果有什么不对的地方,请指正。FileReader首先我们来看一下通用的FileReader对象,就像它的名字一样,是一个文件读取器。之所以是通用对象,是因为它可以读取任何格式的内容。最近尝试用FileReader读取psd、ppt、各种图片等等。虽然很多时候,它上面写的是我们根本看不懂的东西。但是通过一定的转换,理论上我们可以在浏览器中打开任何文件类型。以下是一份MDN的文档FileReaderobject允许web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用File或Blob对象指定要读取的文件或数据。File对象可以来自用户在一个元素上选择文件后返回的FileList对象,也可以来自拖拽操作生成的DataTransfer对象,也可以来自返回的结果在HTMLCanvasElement上执行mozGetAsFile()方法之后。既然是拷贝,就不详细解释了,关键是要知道你要读取的文件的编码类型,然后调用相应的方法来读取。这里是原文。由于FileReader可以将文件读取为各种格式,因此您可以使用此功能来转换编码。比如ArrayBuffer,Blob对象和字符串,base64之间的相互转换/单向转换,有些类型只能单向转换,因为FileReader只接受File或者Blob类型的数据(其实File也是Blob的一种类型),如果数据不能转换成指定的类型,则不能用FileReader转换。constfilereader=newFileReader();constblob=newBlob(['hellofile-reader'],{type:'text/plain'});文件阅读器。onload=e=>{console.log(e.target.result);//输出数据:text/plain;base64,aGVsbG8gZmlsZS1yZWFkZXI=}filereader.readAsDataURL(blob);网上上传的Uint16Array实现String和ArrayBufer之间的转换,其实是有编码长度问题的。我亲身体验过使用FileReader可以避免这个问题。可以调用其readAsArrayBuffer()和readAsText()方法,将指定对象读入ArrayBuffer格式或纯文本格式的数据。当然,FileReader不仅仅可以用于编码转换,它的主要能力还是读取各种文件,配合、DataTransfer、Blob等,可以将任意格式的数据读取到浏览器。Blob对象(BinaryLargeObject)上面已经多次提到Blob对象。我个人认为Blob也是一个非常强大的对象,所以我觉得它在这里非常有用。有必要介绍一下,先看看MDN是怎么说的,Blob对象代表了一个不可变的,原始的类数据文件对象。Blob不一定代表原生JavaScript格式的数据。File接口是基于Blob的,它继承了blob的功能,并集成了对其进行扩展,以支持用户系统上的文件。Blob对象有一个同名的构造函数。构造函数接受2个参数。第一个参数必须是数组类型。即使你只有一件物品,也必须用[]包裹起来。如['hellofile-reader'],第二个参数可选,是一个对象,有2个选项,type和endings,type指定第一个参数的MIME-Type,endings指定第一个的数据参数Format,其可选值有transparent(不变,默认)和native(随系统转换)constblob=newBlob(['hellofile-reader'],{type:'text/plain'});Blob.size可以得到对象中包含的数据的大小(字节),而Blob.type可以得到对象中包含的数据的MIME类型。如果类型未知,则值为空字符串。Blob.slice()方法可以返回一个新的Blob对象,其中包含源Blob对象指定范围内的数据。它总共接收3个参数。前两个参数类似于Array.slice的参数。参数1:起始索引,默认为0参数2:截取结束索引(不包括当前值)参数3:新Blob的MIME类型,默认为空字符串constnewBlob=blob.slice(0,5,'text/plain');分块上传大文件是的,和Blob.size一起吃味道更好。通过URL.createObjectURL(Blobobject),可以将Blob对象转化为链接地址,可以直接在某些DOM的src或href上使用,从而实现前端下载或图片显示。比较神奇的用法是阮老师的webworker教程中的“同页的WebWorker”。这个,结合动态插入到DOM,可以绕过webworker的同源策略吗?如上所述,FileReader只能接受Blob格式的数据(其他格式实际上是Blob的子集)。事实上,Blob只能被FileReader读取。简直就是方便面和火腿肠的最佳搭档。Arraybuffer,类型数组对象,DataView先说Arraybuffer。之所以要引入它,是因为FileReader有一个readAsArrayBuffer()方法。如果要读取的文件是二进制数据,那么应该是最合适的读取方式。读取的数据是一个Arraybuffer对象,老规矩,看定义:ArrayBuffer对象用来表示一个通用的、定长的原始二进制数据缓冲区。ArrayBuffer不能直接操作,必须通过类型数组对象或DataView对象进行操作,这些对象会将缓冲区中的数据以特定的格式表示,通过这些格式来读写缓冲区的内容。Arraybuffer也有一个同名的构造函数,用于创建指定长度的ArrayBuffer对象,所有内容均为0。构造函数接收一个参数,用于指定要创建的内容的长度。例如:让ab=newArrayBuffer(8);//创建一个8字节的ArrayBuffer,因为我们不能直接对Arraybuffer进行操作,所以需要借助其他对象进行操作。都有TypedArray(类型数组对象)和DataView.TypedArray,TypedArray是一类对象的统称,其实JS中没有叫TypedA的阵列对象或构造函数。所以不能直接使用TypedArray。下面是9个TypedArray对象/构造函数Int8Array();Uint8Array();Uint8ClampedArray();Int16Array();Uint16Array();Int32Array();Uint32Array();Float32Array();Float64Array();具体用法参考toMDN:虽然TypedArrayTypedArray不是真正的数组,但它具有与数组几乎相同的API。我们可以像操作数组一样操作TypedArray,所以通过TypedArray我们可以将ArrayBuffer转换成TypedArray,然后进行读写操作,达到操作二进制的目的,下面是一个例子letarrayBuffer=newArrayBuffer(8);console.log(arrayBuffer[0]);//未定义letuint8Array=newUint8Array(arrayBuffer);控制台日志(uint8Array);//[0,0,0,0,0,0,0,0]uint8Array[0]=1;控制台日志(uint8Array[0]);//1console.log(uint8Array);//[1,0,0,0,0,0,0,0]可以看出使用arrayBuffer[0]无法直接获取到ArrayBuffer对象的内容,但是TypedArray可以。直接console.log(arrayBuffer)在console中可以看到[[Int8Array]][[Int16Array]][[Int32Array]][[Uint8Array]]4种类型的TypedArray数据,不过这应该是浏览器为了方便开发人员观察数据,并进行转换而不是实际拥有数据的ArrayBuffer,毕竟对象名称看起来不那么正式(包括[[]])使用arrayBuffer[0]=1作为ArrayBuffer权利对象的下标赋值不会报错,后面可以用同样的路径取值console.log(arrayBuffer[0])//1,但这不代表你操作了数据ArrayBuffer,道理和给数组设置属性是一样的。DataView,DataView提供了和TypedArray类似的功能,和TypedArray不同的是DataView是一个真实的对象,提供了各种方法来操作不同类型的数据,看栗子.letarrayBuffer=newArrayBuffer(8);让dataView=newDataView(arrayBuffer);console.log(dataView.getUint8(1));//0dataView.setUint8(1,2);console.log(dataView.getUint8(1));//2console.log(dataView.getUint16(1));//512dataView.setUint16(1,255);console.log(dataView.getUint16(1));//255console.log(dataView.getUint8(1));//0可以看到,我们可以对同一个数据调用不同的方法,读/写不同类型(长度)的数据,但是在大多数情况下,这会很难得到想要的效果。就像上面的输出,好像不太正常。这是因为一个16位二进制,以8位格式读取,只能读取为两个8位二进制。比如//16-bit10000000000000001//8-bit读出来变成00000000//000000001//1因为前8位都是0所以结果看起来有多个0好像不是有所作为?当数字比较大的时候//应该是256?真不知道这个0000000100000001//用8位读取变成00000001//100000001//1差远了,回过头来看看DataView提供了哪些方法//读取DataView。prototype.getInt8()DataView.prototype.getUint8()DataView.prototype.getInt16()DataView.prototype.getUint16()DataView.prototype.getInt32()DataView.prototype.getUint32()DataView.prototype.getFloat32()DataView.prototype.getFloat64()//写入DataView.prototype.setInt8()DataView.prototype.setUint8()DataView.prototype.setInt16()DataView.prototype.setUint16()DataView.prototype.setInt32()DataView.prototype.setUint32()DataView.prototype.setFloat32()DataView.prototype.setFloat64()比TypedArray少一个Uint8ClampedArray()对吧?以往直接将字符串转base64,我们可能需要在网上照抄别人的方法,而大多数情况下,你没有时间去验证这个方法是否真的靠谱,有没有bug。现在我们可以直接使用内置方法letstr='Iamastring';让a=btoa(str);//a='SSBhbSBhIHN0cmluZw=='让b=atob(a);//b='Iamastring'是的,就是这么简单,除了IE9-,大部分浏览器都支持,具体请参考CanIUse:atobbtoa方法不支持中文和特殊字符,所以保险起见side,encodeURIComponent在转换之前,当然不要忘记在atob之后,返回decodeURIComponent。js包zipjsxml2js最后安利3包jspackhttps://github.com/pgriess/no...js来操作二进制文件,我们用这个包来解析psd文件。jsziphttps://github.com/Stuk/jszipjs操作压缩文件,我们pptx解析成xml的压缩率就靠它了。xml2jshttps://github.com/Leonidas-f...将xml文件转成json,我们分析pptx就是用它来进行pptxxml文件的转换。广告期间,我们40人的前端团队常年招人。在厦门的童鞋们和想来厦门的童鞋们,别吝啬你的简历,发到邮箱:atob('bnVveWFAZ2FvZGluZy5jb20='),期待您的合作如果您对本文有任何意见或建议,请尝试在github上提出问题。最近比较忙,很少去社区。