iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript中怎么对二进制进行操作
  • 940
分享到

JavaScript中怎么对二进制进行操作

2024-04-02 19:04:59 940人浏览 泡泡鱼
摘要

这篇文章将为大家详细讲解有关javascript中怎么对二进制进行操作,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。二进制数据在JS程序里的表达现今世界上几

这篇文章将为大家详细讲解有关javascript中怎么对二进制进行操作,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

二进制数据在JS程序里的表达

现今世界上几乎所有的计算机体系结构都是以字节(byte)为二进制数据的基本单位(注:不是说最小单位),所以二进制常常以字节数组的形式存在于程序当中。例如在C#里面,就用byte[],标准C里面没有byte类型,但可以通过typedef把byte定义为unsigned  char的别名,效果是一样的。

js设计之初似乎根本没想过要处理二进制的东西,加上对类型的极度弱化,对于字节的概念可以说是非常非常的模糊。如果要表达字节数组,那么似乎只能用一个普通数组来表示。

HTML5体系引入了一大堆新的东西,比如XHR2,是可以上传或下载二进制内容的,与之配套的东西就是JS里的ArrayBuffer和Typed  Array了。

ArrayBuffer是一个固定长度的字节序列,你可以通过new  ArrayBuffer(length)来得到一片空间,或者用下文将会介绍的方法从XHR2等途径获取。由于内部实现与数组不一样,ArrayBuffer通常都是连续内存(注意,这只是经验之谈,并不是规范也不是文档所明确的),因此对于高密度的访问操作而言它比JS中的Array速度会快很多(但并不要用它来简单地代替Array)。如果用Chrome的Profile工具查看Heap  Snapshot,会发现ArrayBuffer会被单独列为一类,也许它的内存分配和布局与Array以及其他JS对象有一些差别吧。

ArrayBuffer是不能直接被访问的,因此需要借助Typed Array。Typed  Array是一组具体数据类型的Array-Like类型的统称,包括

  • Int8Array 8位有符号整数,类似于C里面的char

  • Uint8Array 8位无符号整数,类似于C里面的unsigned char

  • Uint8ClampedArray 8位无符号整数,跟Uint8类似,但在溢出处理上不大一样

  • Int16Array 后面这些类型就不罗嗦了

  • Uint16Array

  • Int32Array

  • Uint32Array

  • Float32Array

  • Float64Array

Typed Array的背后是一个ArrayBuffer,也就是说,事实上的数据是存在ArrayBuffer里面的,而Typed  Array只是给你提供了一个某种类型的读写接口,用MDN的话说,叫做

Multiple views on the same data

举个栗子,如果我们有一个ArrayBuffer名为buffer(先不考虑怎么构造这个测试数据),内容如下:

01 02 03 04 05 06 07 08

也就是说它有8个字节,我们分别用它来构造Uint8Array, Uint16Array, Uint32Array,则可以得到

var u8 = new Uint8Array(buffer); // length为8  var u16 = new Uint16Array(buffer); // length为4  var u32 = new Uint32Array(buffer); // length为2

它们的内容分别为

[1, 2, 3, 4, 5, 6, 7, 8]  [513, 1027, 1541, 2055]  [67305985, 134678021]

这不难理解。

可以看出,如果要手工构造上面的测试数据ArrayBuffer,用Uint8Array就会很方便(呃事实上这是我个人最常用的一种Typed  Array)。

而如果用同样的ArrayBuffer构建带符号整数类型,则可能因为整数溢出而得到不同的结果,上面的例子并没有碰到,有兴趣的话可以自己试试。因此使用Typed  Array也可以用来做有符号数和无符号数的转换。

如果你用过canvas的getImageData/putImageData的话,会发现它给你的就是一个Uint8ClampedArray,这东西访问起来速度比JS的原生Array快很多,使得对canvas进行高速的像素操作成为可能。

然而最最重要的一个概念还是:Typed Array不直接存放任何数据,所有对Typed  Array进行读写的操作,最终都会落实到它背后所持有的ArrayBuffer的身上。ArrayBuffer才是真正的raw bytes,而Typed  Array只是一个操作窗口/操作视图(View)。

获取二进制数据

nodejs那边先按住不表,这里谈谈在网页里如何获取二进制数据?常见的办法有3种,1是通过XMLHttpRequest  2,2是通过File和Blob一套相关接口。

通过XMLHttpRequest 2

XHR2的接口跟XHR几乎是一样的,当制定xhr.responseType =  'arraybuffer'以后,在成功获取数据的回调里就可以通过xhr.response来得到请求结果的ArrayBuffer了,然后就可以按照你的意愿来构造各种Typed  Array进行访问。

responseType还可以有blob取值,可以用xhr.response获得Blob对象。

通过File和Blob

html5中提供了对表单的文件控件<input type="file"  />更丰富的操作,可以通过inputDOM对象的.files来获取一个FileList,当然通常浏览器都只提供了单选的文件控件,于是这里都只会有一个File对象。另外,通过拖拽、剪贴板等方式也能获取到File或者Blob。

File继承了Blob,并提供了name, lastModifiedDate等基础元数据,但是依然是一个深度封装,不能直接获取到它的二进制。

Blob是Binary large object的缩写,它与ArrayBuffer的区别是除了raw bytes以外它还提供了mime  type作为元数据。但它依然是无法直接被读写的。

这时候需要借助FileReader的帮忙。FileReader提供了一组用来将Blob读取为更为实用的类型的方法

readAsArrayBuffer()  readAsBinaryString()  readAsDataURL()  readAsText()

例如

var file = get_file_some_how();  var fr = new FileReader();  fr.onload = function(e) {  e.target.result; // 读取的结果  };  fr.readAsDataUrl(file); // readAsArrayBuffer

可以干什么呢?例如图片上传之前的本地预览(甚至基于canvas的编辑)等等都可以实现了。

Blob的其他构造方法多而杂,这里就先不到处搬运文档了。

消费二进制数据

何谓消费?最常见的方式也许就是通过XHR2直接把二进制数据以文件方式POST到服务端去。

这里我比较推荐使用FORMData来构造POST数据。因为在服务端收的时候会比较容易一些,具体有兴趣可以去找找别人的例子。

虽然直接提交ArrayBuffer也是可以的,但是这种时候服务端收到的POST  body会是一大团,用起来不方便。如果要使用FormData来提交ArrayBuffer,需要先将其构造成Blob。

对Typed Array的构造留个心眼

当使用new xxxxxArray(arrayBuffer)这个重载进行构造的时候,它会默认基于此ArrayBuffer进行构造。但当使用new  xxxxArray(another_typed_array)这个重载的时候,则是进行“拷贝构造”,这样两个Typed  Array会指向不同的buffer,需要注意这是否符合预期。

如果需要基于同一个ArrayBuffer来构造Typed Array,可以使用Typed Array的buffer,  byteLength,byteOffset来获取它背后的ArrayBuffer。

Tips(坑)

对内存对齐留个心眼

当使用ArrayBuffer来构造Typed Array的时候,可以指定byteOffset参数,例如

var buffer = get_array_buffer_some_how();  var i16 = new Int16Array(buffer, 10);

上面的代码就能以buffer向后偏移10字节处为起点来构造Int16Array,但是如果将10设置为一个奇数,会发现如下错误:

RangeError: start offset of Int16Array should be a multiple of 2

这是因为Typed  Array对内存对齐有要求,它不能在非对齐的位置建立,同理,Uint32Array和Int32Array则要求偏移量是4字节对齐的。

因此如果你希望在非对齐的位置进行读写,则需要借助DataView的帮忙。

对字节序留个心眼

我们日常中所写的程序,几乎都不需要关心字节序,因此这个问题没那么严重,知道自己的程序会有字节序问题的人,开发到这里也肯定会知道问题的存在,但这里还是稍微提一下。

按照MDN的说法,Typed  Array只会使用当前平台的字节序,例如我们现在用的桌面电脑不论PC还是Mac都是x86/x64的,也就是little-endian了。

使用DataView,不仅可以解决上面说到的内存对齐的问题,还可以指定读写时的字节序,具体参数都在文档里面了,就不搬运了。

使用DataView配合Typed Array也可以做到一个检测当前平台字节序的技巧:

function isLittleEndian() {  var buf = new ArrayBuffer(2);  var view = new DataView(buf);  view.setInt16(0, 256, true);//显式以little endian写入数据  // 此时buf里的内存布局应该是 00 01   var i16 = new Int16Array(buf);  // 如果以little endian读取,它就是256;以big endian读取,则是1  return (i16[0] === 256);  }

关于JavaScript中怎么对二进制进行操作就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: JavaScript中怎么对二进制进行操作

本文链接: https://www.lsjlt.com/news/73253.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript中怎么对二进制进行操作
    这篇文章将为大家详细讲解有关JavaScript中怎么对二进制进行操作,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。二进制数据在JS程序里的表达现今世界上几...
    99+
    2024-04-02
  • VB.NET中怎么对二进制文件进行操作
    今天就跟大家聊聊有关VB.NET中怎么对二进制文件进行操作,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。VB.NET二进制文件操作主要应用的方法和函数有:Open,Close,Get...
    99+
    2023-06-17
  • JavaScript 中怎么对Cookie进行操作
    本篇文章为大家展示了JavaScript 中怎么对Cookie进行操作,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Cookie 只是存储在计算机浏览器中的小型文本...
    99+
    2024-04-02
  • JavaScript中怎么对数组进行操作
    本篇文章给大家分享的是有关JavaScript中怎么对数组进行操作,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。js对数组对象的操作以及方法的...
    99+
    2024-04-02
  • ADO.NET中怎么对SqlDataAdapter进行操作
    本篇文章为大家展示了ADO.NET中怎么对SqlDataAdapter进行操作,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。ADO.NET SqlDataAdapter对象SqlDataAdapte...
    99+
    2023-06-17
  • C++中怎么对Test进行操作
    C++中怎么对Test进行操作,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。静态测试 C++Test内嵌了业界最出名的Effective C++(epcc)、M...
    99+
    2023-06-17
  • node.js中怎么对CQS进行操作
    本篇文章为大家展示了node.js中怎么对CQS进行操作,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。  怎样使用node.js来操作CQS  安装:  $npmi...
    99+
    2024-04-02
  • C#中怎么对Word进行操作
    C#中怎么对Word进行操作,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。导入COM库:Microsoft word 11.0 Object Library.引用里面就增加了:...
    99+
    2023-06-17
  • C++ 中怎么对Endian进行操作
    C++ 中怎么对Endian进行操作,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1.判断CPU的C++ Endian:union {&nb...
    99+
    2023-06-17
  • C#中怎么对StreamWriter进行操作
    今天就跟大家聊聊有关C#中怎么对StreamWriter进行操作,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。C# StreamWriter写文件的操作实例://实例化一个保存文件对...
    99+
    2023-06-17
  • node.js中怎么对文件进行操作
    这篇文章将为大家详细讲解有关node.js中怎么对文件进行操作,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一、文件操作在文件操作里,主要是有文件读写,创建...
    99+
    2024-04-02
  • Jave中怎么对枚举进行操作
    这篇文章给大家介绍Jave中怎么对枚举进行操作,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。枚举其实就是一种类型,跟int, char 这种差不多,就是定义变量时限制输入的,你只能够赋enum里面规定的值。定义枚举 方...
    99+
    2023-06-17
  • QT中怎么对Mat类进行操作
    本篇内容主要讲解“QT中怎么对Mat类进行操作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“QT中怎么对Mat类进行操作”吧!一、类型转换opencv在QT中的应用通常会涉及到这三者的转换,即M...
    99+
    2023-07-02
  • VBScript 中怎么对文件进行操作
    这期内容当中小编将会给大家带来有关VBScript 中怎么对文件进行操作,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。创建文本文件 复制代码 代码如下:Set objFSO = CreateObject(...
    99+
    2023-06-08
  • Python中怎么对文件进行操作
    Python中怎么对文件进行操作,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。编码方式编码方式的历史大致为ASCII ->gb2312->unicode->u...
    99+
    2023-06-16
  • 怎么在Django中对View进行操作
    本篇文章给大家分享的是有关怎么在Django中对View进行操作,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Django的View一个视图函数(类),简称视图,是一个简单的P...
    99+
    2023-06-14
  • C#中怎么对内存进行操作
    C#中怎么对内存进行操作,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。引用System.Runtime.InteropServices命名空间。该命名空间下的Marshal...
    99+
    2023-06-17
  • html5中怎么对document metadata进行操作
    这篇文章将为大家详细讲解有关html5中怎么对document metadata进行操作,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1.操作Documen...
    99+
    2024-04-02
  • VB.NET中怎么对EXCEL表进行操作
    今天就跟大家聊聊有关VB.NET中怎么对EXCEL表进行操作,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。读写VB.NET EXCEL表:VB本身提自动化功能可以读写EXCEL表,其...
    99+
    2023-06-17
  • Golang中怎么对切片进行操作
    在Golang中,可以通过以下方式对切片进行操作: 创建切片: slice := []int{1, 2, 3, 4, 5} ...
    99+
    2024-03-13
    Golang
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作