JS 字节流 解析


前言

提示:最近作者在工作之余,遇到了关于字节数据传输,前端解析数据的问题,为此写了一个用于处理该类问题的 js 库。


提示:以下是本篇文章正文内容,下面案例可供参考

JS 源码

代码如下(示例):

var BOOL_TYPE = 0,       // Bool
    INT8_TYPE = 1,       // Char
    UINT8_TYPE = 2,      // UChar
    INT16_TYPE = 3,      // Short
    UINT16_TYPE = 4,     // UShort
    INT32_TYPE = 5,      // Int
    INT64_TYPE = 6       // Long
    UINT32_TYPE = 7,     // UInt
    FLOAT32_TYPE = 8,    // Float
    FLOAT64_TYPE = 9,    // Double
    BYTE_TYPE = 10,      // Byte
    Str_TYPE = 11;  
    
// type:数据类型, Bin:二进制流,begin:数据起始位置(字节),Num: 1
function TypedArrays(Type, Bin) {//, begin, Num
    //var _num = 1;
    switch (Type) {
        case BOOL_TYPE: return Bin[0] == 1 ? true : false;
        case INT8_TYPE: return toInt8(Bin); 
        case UINT8_TYPE: return toUint8(Bin); 
        case INT16_TYPE: return toInt16(Bin);    
        case UINT16_TYPE: return toUint16(Bin);  
        case INT32_TYPE: return toInt32(Bin);    
        case INT64_TYPE: return toInt64(Bin);    
        case UINT32_TYPE: return toUint32(Bin);  
        case FLOAT32_TYPE: return toFloat32(Bin);
        case FLOAT64_TYPE: return toFloat64(Bin);
        case BYTE_TYPE: return toBytes(Bin);
        case Str_TYPE: return toString(Bin);
        default: return -1;
    }
}

// 截取指定大小数据并转换成指定的数据类型
function ByteToType(Type, Bin, begin, Num) {
    return TypedArrays(Type, Bin.splice(begin, Num));//, begin, Num);
}

// ASCII to char
function ASCII2Char(v) { return String.fromCharCode(v); }

// ASCII to string
function ASCII2Str(Bin, StartByte, Type, MsgLen) {
    var MsgName = "";
    var Index = 0;

    while (Index < MsgLen) {
        var AsciiValue = TypedArrays(Type, Bin, StartByte, 1); StartByte += 1;
        if (AsciiValue != 0)
            MsgName += ASCII2Char(AsciiValue);
        else
            return MsgName;
        Index++;
    }
    return MsgName;
}
function byteToString(arr) {
    if (typeof arr === 'string') {
        return arr;
    }
    var str = '',
        _arr = arr;
    for (var i = 0; i < _arr.length; i++) {
        var one = _arr[i].toString(2),
            v = one.match(/^1+?(?=0)/);
        if (v && one.length == 8) {
            var bytesLength = v[0].length;
            var store = _arr[i].toString(2).slice(7 - bytesLength);
            for (var st = 1; st < bytesLength; st++) {
                if (_arr.length > i + st) {
                    store += _arr[st + i].toString(2).slice(2);
                } else {
                    store = '000000';
                }
            }
            str += String.fromCharCode(parseInt(store, 2));
            i += bytesLength - 1;
        } else {
            str += String.fromCharCode(_arr[i]);
        }
    }
    return str;
}
           
//构建一个视图,把字节数组写到缓存中,索引从0开始,大端字节序
function getView(bytes) {
    var view = new DataView(new ArrayBuffer(bytes.length));
    for (var i = 0; i < bytes.length; i++) {
        view.setUint8(i, bytes[i]);
    }
    return view;
}

function toString(bytes) {
    //var data = getView(bytes);
    return byteToString(bytes);
}

//对应数组,或单数结果
function toBytes(bytes) {
    if (bytes.length > 1) {
        return bytes;
    } else {
        return bytes[0];
    }
}
//将字节数组转成有符号的8位整型,大端字节序
function toInt8(bytes) {
    return getView(bytes).getInt8();
}
//将字节数组转成无符号的8位整型,大端字节序
function toUint8(bytes) {
    return getView(bytes).getUint8();
}
//将字节数组转成有符号的16位整型,大端字节序
function toInt16(bytes) {
    return new Int16Array(getView(bytes).buffer, 0, 1)[0]; 
}
//将字节数组转成无符号的16位整型,大端字节序
function toUint16(bytes) {
    return new Uint16Array(getView(bytes).buffer, 0, 1)[0];
}
//将字节数组转成有符号的32位整型,大端字节序
function toInt32(bytes) {
    return new Int32Array(getView(bytes).buffer, 0, 1)[0]; 
}
//将字节数组转成无符号的32位整型,大端字节序
function toUint32(bytes) {
    return new Uint32Array(getView(bytes).buffer, 0, 1)[0]; 
}
//将字节数组转成有符号的64位整型,大端字节序
function toInt64(bytes) {
    return new BigInt64Array(getView(bytes).buffer, 0, 1)[0];
}
//将字节数组转成有符号的64位整型,大端字节序
function toUint64(bytes) {
    return new BigUint64Array(getView(bytes).buffer, 0, 1)[0];
}
//将字节数组转成32位浮点型,大端字节序
function toFloat32(bytes) {
    return getView(bytes).getFloat32();
}
//将字节数组转成64位浮点型,大端字节序
function toFloat64(bytes) {
    return new Float64Array(getView(bytes).buffer, 0, 1)[0]; 
}
//将数值写入到视图中,获得其字节数组,大端字节序
function getUint8Array(len, setNum) {
    var buffer = new ArrayBuffer(len);  //指定字节长度
    setNum(new DataView(buffer));  //根据不同的类型调用不同的函数来写入数值
    return new Uint8Array(buffer); //创建一个字节数组,从缓存中拿取数据
}
//得到一个8位有符号整型的字节数组,大端字节序
function getInt8Bytes(num) {
    return getUint8Array(1, function (view) { view.setInt8(0, num); })
}
//得到一个8位无符号整型的字节数组,大端字节序
function getUint8Bytes(num) {
    return getUint8Array(1, function (view) { view.setUint8(0, num); })
}
//得到一个16位有符号整型的字节数组,大端字节序
function getInt16Bytes(num) {
    return getUint8Array(2, function (view) { view.setInt16(0, num); })
}
//得到一个16位无符号整型的字节数组,大端字节序
function getUint16Bytes(num) {
    return getUint8Array(2, function (view) { view.setUint16(0, num); })
}
//得到一个32位有符号整型的字节数组,大端字节序
function getInt32Bytes(num) {
    return getUint8Array(4, function (view) { view.setInt32(0, num); })
}
//得到一个32位无符号整型的字节数组,大端字节序
function getUint32Bytes(num) {
    return getUint8Array(4, function (view) { view.setUint32(0, num); })
}
//得到一个32位浮点型的字节数组,大端字节序
function getFloat32Bytes(num) {
    return getUint8Array(4, function (view) { view.setFloat32(0, num); })
}
//得到一个64位浮点型的字节数组,大端字节序
function getFloat64Bytes(num) {
    return getUint8Array(8, function (view) { view.setFloat64(0, num); })
}
    

使用步骤

代码如下(示例):

ByteToType(INT32_TYPE, [0,1,1,2], 0, 4); //转换类型 int32,源数据,取值下标,取几位

总结

提示:以上简单示例,仅为模板,大家可以有自己更好的思路哦。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用 Flask 的 Response 对象来同时返回字节流数据和数组数据。以下是一个示例代码: ```python from flask import Flask, Response import numpy as np app = Flask(__name__) @app.route('/') def index(): # 生成一些随机数据 data = np.random.rand(10) # 将数据转换为字节流 data_bytes = data.tobytes() # 创建一个 Response 对象,同时包含字节流数据和数组数据 response = Response(data_bytes, mimetype='application/octet-stream') response.headers['X-Data'] = str(data.tolist()) return response if __name__ == '__main__': app.run() ``` 在这个示例中,我们使用 NumPy 生成了一些随机数据,并将其转换为字节流。然后,我们创建了一个 Flask 的 Response 对象,将字节流数据作为第一个参数传递,并将 mimetype 设置为 'application/octet-stream',表示这是一个二进制数据流。我们还将数组数据转换为字符串,并将其添加到 Response 对象的 headers 中,以便前端可以访问它。 当您访问这个 Flask 应用程序时,它将同时返回字节流数据和数组数据。您可以使用 JavaScript 从 Response 对象中获取这些数据,例如: ```javascript fetch('/') .then(response => { const dataBytes = response.arrayBuffer(); const dataStr = response.headers.get('X-Data'); const data = JSON.parse(dataStr); // 处理数据... }); ``` 在这个 JavaScript 代码中,我们使用 fetch 函数从 Flask 应用程序中获取数据。我们使用 arrayBuffer 方法获取字节流数据,使用 headers.get 方法获取数组数据,并将其解析JSON 对象。然后,我们可以使用这些数据进行进一步的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值