Int8Array uint16Array Int32Array数据类型--文件流 大文件分片-DataView

复合视图

  var buffer = new ArrayBuffer(24);

  var idView = new Uint32Array(buffer, 0, 1);
  var usernameView = new Uint8Array(buffer, 4, 16);
  var amountDueView = new Float32Array(buffer, 20, 1);

Int8Array uint16Array Int32Array 定义数据类型

无符号整型数组(取值范围) 
var arr=new Uint8Array([85, 15, 0, 70, 3, 2, 39, 0, 17, 102, 0, 75, 0, 13, 165]);
// 二进制转 16进制
arr[0].toString(16)
arr[1].toString(16)
[[Int8Array]]: Int8Array(20) [90, 10, 3, 16, 5, 2, 15, 33, 59, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[[Int16Array]]: Int16Array(10) [2650, 4099, 517, 8463, -5317, 0, 0, 0, 0, 0]
[[Int32Array]]: Int32Array(5) [268634714, 554631685, 60219, 0, 0]
[[Uint8Array]]: Uint8Array(20) [90, 10, 3, 16, 5, 2, 15, 33, 59, 235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
byteLength: (...)
__proto__: ArrayBuffer
[[IsDetached]]: false

二进制内存 转十六进制   进行解读   
function ab2hex(buffer) {
  const hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('')
}
ab2hex([90, 10, 3, 16, 5, 2, 15, 33, 59, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
"5a 0a 03 10 05 02 0f 21 3b eb 00000000000000000000"



//转码    //  5A 0A 03 10 05 02 0F 21 3B EB   十六进制转二进制 setUint8 写入内存
function hexStringToArrayBuffer(str) {
  if (!str) {
    return new ArrayBuffer(0);
  }
  var buffer = new ArrayBuffer(str.length);
  let dataView = new DataView(buffer)
  let ind = 0;
  for (var i = 0, len = str.length; i < len; i += 2) {
    let code = parseInt(str.substr(i, 2), 16)
    dataView.setUint8(ind, code)
    ind++
  }
  return buffer;
}
hexStringToArrayBuffer('5A0A031005020F213BEB')
[[Int8Array]]: Int8Array(20) [90, 10, 3, 16, 5, 2, 15, 33, 59, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[[Int16Array]]: Int16Array(10) [2650, 4099, 517, 8463, -5317, 0, 0, 0, 0, 0]
[[Int32Array]]: Int32Array(5) [268634714, 554631685, 60219, 0, 0]
[[Uint8Array]]: Uint8Array(20) [90, 10, 3, 16, 5, 2, 15, 33, 59, 235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
byteLength: (...)
__proto__: ArrayBuffer
[[IsDetached]]: false

03Int8Array Int16Array Int32Array

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

</head>

<body>
    <script>

        // 数组中每个元素的大小(以字节为单位)。
        // 语法
        // JavaScript
        // var arraySize = uint16Array.BYTES_PER_ELEMENT

        // var int32 = new Int32Array(3);//int32数组 3表示占位符几个 开辟内存中
        // console.log(int32) //数组对象
        // int32[0] = 42;  //数组第一位数赋值
        // console.log(int32[0]); // 42 读取第一位数数组
        // console.log(int32.length); // 3 数组长度
        // console.log(int32.BYTES_PER_ELEMENT); // 4个字节 
        // // 1字节(Byte,缩写为B)由8个位组成,即1Byte=8bit,是存储器的基本单位,通常被作为一个存储单元。通常情况下,把B称为字节
        // // 1汉字=2字节1字节(Byte)=8字位=8个二进制数1字位(bit)=1个二进制数1B=8b1KB

        // var int16 = new Int16Array(3)
        // console.log(int16);
        // int16[0] = 42;
        // console.log(int16[0])
        // console.log(int16.length)
        // console.log(int16.BYTES_PER_ELEMENT)


        // var int8 = new Int8Array(3)
        // console.log(int8);
        // int8[0] = 42;
        // console.log(int8[0])
        // console.log(int8.length)
        // console.log(int8.BYTES_PER_ELEMENT)

        //数组转化成视图数组
        // var int8 = new Int8Array([1, 2]) //映射到内存中
        // console.log(int8);
        // console.log(int8[0])
        // console.log(int8.length)
        // console.log(int8.BYTES_PER_ELEMENT)

        // //试图数组转化普通数组
        // var normalArray = Array.apply([], int8);
        // console.log(normalArray)

        // var b = new ArrayBuffer(8);
        // // (3)byteLength属性和byteOffset属性

        // // byteLength属性返回类型化数组占据的内存长度,单位为字节。byteOffset属性返回类型化数组从底层ArrayBuffer对象的哪个字节开始。这两个属性都是只读属性。
        // var v1 = new Int32Array(b);
        // var v2 = new Uint8Array(b, 2);
        // var v3 = new Int16Array(b, 2, 2);

        // v1.byteLength // 8
        // v2.byteLength // 6
        // v3.byteLength // 4

        // v1.byteOffset // 0
        // v2.byteOffset // 2
        // v3.byteOffset // 2
        // // 注意将byteLength属性和length属性区分,前者是字节长度,后者是成员长度。
        // var a = new Int16Array(8);

        // a.length // 8
        // a.byteLength // 16

        // var iterable = function* () { yield* [1, 2, 3]; }();
        // var int32 = new Int32Array(iterable);
        // console.log(int32)
        // Int32Array[1, 2, 3]



        //完整的资料  https://blog.csdn.net/lichwei1983/article/details/43893025
        // 视图的操作
        // 建立了视图以后,就可以进行各种操作了。这里需要明确的是,视图其实就是普通数组,语法完全没有什么不同,只不过它直接针对内存进行操作,而且每个成员都有确定的数据类型。所以,视图就被叫做“类型化数组”。

        // (1)数组操作

        // 普通数组的操作方法和属性,对类型化数组完全适用。

        // var buffer = new ArrayBuffer(16);

        // var int32View = new Int32Array(buffer);

        // for (var i = 0; i < int32View.length; i++) {
        //     int32View[i] = i * 2;
        // }
        // 上面代码生成一个16字节的ArrayBuffer对象,然后在它的基础上,建立了一个32位整数的视图。由于每个32位整数占据4个字节,所以一共可以写入4个整数,依次为0,2,4,6。

        // 如果在这段数据上接着建立一个16位整数的视图,则可以读出完全不一样的结果。

        // var int16View = new Int16Array(buffer);

        // for (var i = 0; i < int16View.length; i++) {
        //     console.log("Entry " + i + ": " + int16View[i]);
        // }
        // // Entry 0: 0
        // // Entry 1: 0
        // // Entry 2: 2
        // // Entry 3: 0
        // // Entry 4: 4
        // // Entry 5: 0
        // // Entry 6: 6
        // // Entry 7: 0
        // 由于每个16位整数占据2个字节,所以整个ArrayBuffer对象现在分成8段。然后,由于x86体系的计算机都采用小端字节序(little endian),相对重要的字节排在后面的内存地址,相对不重要字节排在前面的内存地址,所以就得到了上面的结果。

        // 比如,一个占据四个字节的16进制数0x12345678,决定其大小的最重要的字节是“12”,最不重要的是“78”。小端字节序将最不重要的字节排在前面,储存顺序就是78563412;大端字节序则完全相反,将最重要的字节排在前面,储存顺序就是12345678。目前,所有个人电脑几乎都是小端字节序,所以类型化数组内部也采用小端字节序读写数据,或者更准确的说,按照本机操作系统设定的字节序读写数据。

        // 这并不意味大端字节序不重要,事实上,很多网络设备和特定的操作系统采用的是大端字节序。这就带来一个严重的问题:如果一段数据是大端字节序,类型化数组将无法正确解析,因为它只能处理小端字节序!为了解决这个问题,JavaScript引入DataView对象,可以设定字节序,下文会详细介绍。

        // 下面是另一个例子。

        // // 假定某段buffer包含如下字节 [0x02, 0x01, 0x03, 0x07]
        // // 计算机采用小端字节序
        // var uInt16View = new Uint16Array(buffer);

        // // 比较运算 
        // if (bufView[0] === 258) {
        //     console.log("ok");
        // }

        // // 赋值运算
        // uInt16View[0] = 255;    // 字节变为[0xFF, 0x00, 0x03, 0x07]
        // uInt16View[0] = 0xff05; // 字节变为[0x05, 0xFF, 0x03, 0x07]
        // uInt16View[1] = 0x0210; // 字节变为[0x05, 0xFF, 0x10, 0x02]
        // 总之,与普通数组相比,类型化数组的最大优点就是可以直接操作内存,不需要数据类型转换,所以速度快得多。

        // (2)buffer属性

        // 类型化数组的buffer属性,返回整段内存区域对应的ArrayBuffer对象。该属性为只读属性。

        // var a = new Float32Array(64);
        // var b = new Uint8Array(a.buffer);
        // 上面代码的a对象和b对象,对应同一个ArrayBuffer对象,即同一段内存。

        // (3)byteLength属性和byteOffset属性

        // byteLength属性返回类型化数组占据的内存长度,单位为字节。byteOffset属性返回类型化数组从底层ArrayBuffer对象的哪个字节开始。这两个属性都是只读属性。

        // var b = new ArrayBuffer(8);

        // var v1 = new Int32Array(b);
        // var v2 = new Uint8Array(b, 2);
        // var v3 = new Int16Array(b, 2, 2);

        // v1.byteLength // 8
        // v2.byteLength // 6
        // v3.byteLength // 4

        // v1.byteOffset // 0
        // v2.byteOffset // 2
        // v3.byteOffset // 2
        // 注意将byteLength属性和length属性区分,前者是字节长度,后者是成员长度。

        // var a = new Int16Array(8);

        // a.length // 8
        // a.byteLength // 16
        // (4)set方法

        // 类型化数组的set方法用于复制数组,也就是将一段内容完全复制到另一段内存。

        // var a = new Uint8Array(8);
        // var b = new Uint8Array(8);

        // b.set(a);
        // 上面代码复制a数组的内容到b数组,它是整段内存的复制,比一个个拷贝成员的那种复制快得多。set方法还可以接受第二个参数,表示从b对象哪一个成员开始复制a对象。

        // var a = new Uint16Array(8);
        // var b = new Uint16Array(10);

        // b.set(a, 2)
        // 上面代码的b数组比a数组多两个成员,所以从b[2]开始复制。

        // (5)subarray方法

        // subarray方法是对于类型化数组的一部分,再建立一个新的视图。

        // var a = new Uint16Array(8);
        // var b = a.subarray(2, 3);

        // a.byteLength // 16
        // b.byteLength // 2
        // subarray方法的第一个参数是起始的成员序号,第二个参数是结束的成员序号(不含该成员),如果省略则包含剩余的全部成员。所以,上面代码的a.subarray(2, 3) ,意味着b只包含a[2]一个成员,字节长度为2。

        // (6)ArrayBuffer与字符串的互相转换

        // ArrayBuffer转为字符串,或者字符串转为ArrayBuffer,有一个前提,即字符串的编码方法是确定的。假定字符串采用UTF - 16编码(JavaScript的内部编码方式),可以自己编写转换函数。

        // // ArrayBuffer转为字符串,参数为ArrayBuffer对象
        // function ab2str(buf) {
        //     return String.fromCharCode.apply(null, new Uint16Array(buf));
        // }

        // // 字符串转为ArrayBuffer对象,参数为字符串
        // function str2ab(str) {
        //     var buf = new ArrayBuffer(str.length * 2); // 每个字符占用2个字节
        //     var bufView = new Uint16Array(buf);
        //     for (var i = 0, strLen = str.length; i < strLen; i++) {
        //         bufView[i] = str.charCodeAt(i);
        //     }
        //     return buf;
        // }
        // 复合视图
        // 由于视图的构造函数可以指定起始位置和长度,所以在同一段内存之中,可以依次存放不同类型的数据,这叫做“复合视图”。

        // var buffer = new ArrayBuffer(24);

        // var idView = new Uint32Array(buffer, 0, 1);
        // var usernameView = new Uint8Array(buffer, 4, 16);
        // var amountDueView = new Float32Array(buffer, 20, 1);
        // 上面代码将一个24字节长度的ArrayBuffer对象,分成三个部分:

        // 字节0到字节3:1个32位无符号整数
        // 字节4到字节19:16个8位整数
        // 字节20到字节23:1个32位浮点数
        // 这种数据结构可以用如下的C语言描述:

        // struct someStruct {
        //     unsigned long id;
        //     char username[16];
        //     float amountDue;
        // }

    </script>
</body>

</html>

04ArrayBuffer

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

</head>

<body>
    <script>
        //var buffer1 = new ArrayBuffer(32);//可视化数组的基础 直接在内存开辟缓存空间  32是字节
        // 类型化数组是建立在ArrayBuffer对象的基础上的。它的作用是,分配一段可以存放数据的连续内存区域
        //var buffer = new ArrayBuffer(32);
        //buffer.byteLength  //32
        // 上面代码生成了一段32字节的内存区域。
        // ArrayBuffer对象的byteLength属性,返回所分配的内存区域的字节长度。
        //var buffer = new ArrayBuffer(8);
        //var newBuffer = buffer.slice(0, 3);
        // 上面代码拷贝buffer对象的前3个字节,生成一个新的ArrayBuffer对象。slice方法其实包含两步,第一步是先分配一段新内存,第二步是将原来那个ArrayBuffer对象拷贝过去。
        // slice方法接受两个参数,第一个参数表示拷贝开始的字节序号,第二个参数表示拷贝截止的字节序号。如果省略第二个参数,则默认到原ArrayBuffer对象的结尾。
        // 除了slice方法,ArrayBuffer对象不提供任何直接 {{读写内存}} 的方法,只允许在其上方建立视图,然后通过视图读写。


        // var buffer = new ArrayBuffer(12);//开辟缓存
        // console.log(buffer)
        // var x = new Int32Array(buffer);//转化32 可视化数组
        // console.log(x)
        // x[1] = 1234;//进行赋值操作
        // var slice = buffer.slice(4);//分割缓存空间 第4位 都是buffer内存
        // console.log(slice)
        // var y = new Int32Array(slice);//转化新的32 可视化数组
        // console.log(x[1]);
        // console.log(y[0]);
        // x[1] = 6789;//修改数组中的值
        // console.log(x[1]);
        // console.log(y[0]);


        // ArrayBuffer转为字符串,参数为ArrayBuffer对象
        function ab2str(buf) {
            return String.fromCharCode.apply(null, new Uint16Array(buf));
        }

        // 字符串转为ArrayBuffer对象,参数为字符串
        function str2ab(str) {
            console.log(str.length * 2)
            var buf = new ArrayBuffer(str.length * 2); // 每个字符占用2个字节
            console.log(buf)
            var bufView = new Uint16Array(buf);
            for (var i = 0, strLen = str.length; i < strLen; i++) {
                bufView[i] = str.charCodeAt(i);
            }
            return buf;
        }
        var buf = str2ab('你好')
        console.log(buf)
        var ab2str = ab2str(buf);
        console.log(ab2str)
    </script>
</body>

</html>

05Blobupdown

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

</head>

<body>
    <script>
        var input = document.getElementById("file");   // input file
        input.onchange = function () {
            var file = this.files[0];
            if (!!file) {
                var reader = new FileReader();
                reader.readAsArrayBuffer(file);
                reader.onload = function () {
                    var binary = this.result;
                    upload(binary);
                }
            }
        }

        //文件上传
        function upload(binary) {
            var xhr = new XMLHttpRequest();
            xhr.open("POST", "http://xxxx/opload");
            xhr.overrideMimeType("application/octet-stream");
            //直接发送二进制数据
            if (xhr.sendAsBinary) {
                xhr.sendAsBinary(binary);
            } else {
                xhr.send(binary);
            }

            // 监听变化
            xhr.onreadystatechange = function (e) {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        // 响应成功       
                    }
                }
            }
        }
    </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

web修理工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值