起因
事情是这样的:从产品那里接到需求,要把pdf文件在移动端展示并保存在手机相册里。保存到手机相册中,那就要把pdf文件变成图片。网上搜索一下,Mozilla的pdf.js库刚好可以。于是开始看官方文档,但文档是都是由源代码的注释生成的,也就看到一部分源代码。pdf.js源码里有一个重要的方法getDocument,在这个方法上的注释写到:
@param
{string|TypedArray|DocumentInitParameters|PDFDataRangeTransport} src Can be a url to where a PDF is located, a typed array (Uint8Array
)
already populated with data or parameter object.
可以是URL也可以是Uint8Array?Uint8Array是什么?正是这里的Uint8Array才有接下来关于Uint8Array(TypedArray)的一系列知识点的学习。
历史
JavaScript在设计时只是简单运行于网页的脚本语言,远没有预想到会发展到今时今日的地步。起初JavaScript在业务场景中不会处理到复杂的数据和交互逻辑,但随着互联网的发展,网页已经不仅仅局限简单的文字图片展示等基础功能,逐步需要囊括视频播放、音频播放、在线绘画等功能。在此业务场景下,JavaScript亟需更多能力以处理音视频等二进制数据。但JavaScript的基本类型Boolean、Function、String…等都无法处理音视频等二进制数据(早期由Flash插件代为处理),也不存在某个对象拥有处理二进制流数据的能力。随着时间推移,Node的出现让JavaScript第一次能够处理文件(二进制流数据)的能力——Buffer。但Node依旧只能让运行在server端的JavaScript具有处理二进制数据的能力,client端依旧无法处理二进制数据。直到2015年的新规范ES2015(ES6)中,才定义了具有处理二进制数据能力的对象TypedArray。先来看看早于TypedArray出现的Buffer是什么:
Buffer
在Node文档中描写Buffer道:
在引入TypedArray之前,JavaScript并没有读取或者操作流或二进制数据数据的机制。而Buffer正是因此被引入Node.js API中,使得JavaScript能够介入TCP字节流、文件操作系统和其他场景并能处理其中的内容。随着TypedArray的普及,Buffer的地位变成更优化和更适合的Node端Uint8Array类型的TypedArray实现。
显然Buffer是为在HTTP和文件系统的场景下给予JavaScript处理数据的能力而诞生的,并且概念上Buffer属于TypedArray。那么Buffer是如何读取和操作数据内容的呢?
Buffer提供以下几个API:
- 创建缓存区:Buffer.from、Buffer.alloc;(废弃
new Buffer()
确保新建的 Buffer 实例的内容不会包含敏感数据) - Buffer.concat像数组似的链接两个Buffer;
- Buffer.compare对比两个缓存区。
下面是关于Node中转文件的简单例子:
?Node文件中转-Buffer
async function nodeBuffer(){
let query = ctx.request.query;
let downloadPath = query.path;
let instance = axios.create({
headers: {
'content-type': 'application/octet-stream'
},
})
delete query.path;
await instance.get(downloadPath, query)
.then(res => {
ctx.attachment(query.name)
ctx.set('Encoding',