uniapp APP读取bin文件(仅测试安卓可用)

1.解析bin文件内容

    getData(path) {
      return new Promise(
        (resolve) => {
          uni.downloadFile({
            url: path, // .bin 文件 URL
            success: (res) => {
              if (res.statusCode === 200) {
                //文件读写是一个异步请求 用promise包起来方便使用时的async+await
                plus.io.resolveLocalFileSystemURL(
                  res.tempFilePath, //请求文件系统
                  (fileEntry) => {
                    fileEntry.file(function (file) {
                      let fileReader = new plus.io.FileReader(); //new一个可以用来读取文件的对象fileReader
                      fileReader.readAsDataURL(file); //读文件的格式
                      fileReader.onerror = (e) => {
                        //读文件失败
                        console.log("获取文件失败", fileReader.error);
                        return;
                      };
                      fileReader.onload = (e) => {
                        //读文件成功
                        var u8arr = (function (path, name) {
                          var arr = path.split(","),
                            mime = arr[0].match(/:(.*?);/)[1],
                            bstr = atob(arr[1]),
                            n = bstr.length,
                            u8arr = new Uint8Array(n);
                          while (n--) {
                            u8arr[n] = bstr.charCodeAt(n);
                          }
                          resolve(u8arr);
                        })(e.target.result, fileEntry.name);
                      };
                    });
                  },
                  (error) => {
                    console.log("新建获取文件失败", error);
                    return;
                  }
                );
              }
            },
            fail: (err) => {
              console.log("下载失败:", err);
            },
          });
        },
        (failure) => {
          console.log("请求文件系统失败", failure.message);
          return;
        }
      );
    },

2.使用

 let pathUrl = '你的在线.bin文件地址'
 this.getData(pathUrl).then((res) => {
    // arrayBuffer 文件
    console.log(res);
    // 转16进制
    let hex = this.arraybufferTo2Hex(res);
    console.log(hex);
 });



 // 转16进制
 arraybufferTo2Hex(buffer) {
   return Array.prototype.map
      .call(new Uint8Array(buffer), (x) => ("00" + x.toString(16)).slice(-2))
      .join(" ");
 },

<think>我们正在开发一个UniApp应用,需要从本地文件系统读取一个.bin文件(小端序),并将其解析为16进制数据。同时,我们需要详细的日志输出以方便调试。 由于UniApp基于Vue.js,并且可以跨平台运行,我们将使用uni-app文件API来读取文件。考虑到.bin文件是小端序,我们需要在读取后正确解析字节顺序。 步骤: 1. 用户选择文件:我们可以使用uni.chooseFile让用户选择文件,或者直接使用已知的本地文件路径(如果是已知路径)。 2. 读取文件:使用uni.readFile读取文件,得到ArrayBuffer。 3. 将ArrayBuffer转换为字节数组(Uint8Array)。 4. 由于要求是小端序,我们在解析多字节数据(如16位、32位整数等)时需要注意字节顺序。但问题要求解析成16进制数据,我们可以先按字节(8位)读取,然后每个字节转换为两个16进制字符。这样就不涉及字节顺序(因为每个字节是独立的)。但是,如果后续需要将多个字节组合成更大的整数(比如int, float)并且要求小端序,则需要按照小端序组合。不过,当前需求只是解析成16进制字符串,所以我们可以先按字节转换为16进制字符串,然后连接起来。注意:小端序的影响在于多字节数据的解释,而这里我们只是按字节展示,所以不需要考虑小端序(因为每个字节是独立的)。 5. 但是,如果需求是将整个文件的内容转换为一个16进制字符串,那么我们可以逐字节转换。但是,如果文件很大,可能会造成性能问题,所以要注意文件大小。 然而,问题描述中要求的是“解析成16进制数据”,并没有要求组合成多字节整数,所以我们按字节转换为16进制字符串即可。 日志输出:在关键步骤输出日志,如文件读取开始、读取成功、文件大小、转换开始、转换结果(可以只输出部分,因为可能很大)等。 注意:UniApp读取文件需要使用uni.readFile,但该API在H5平台和APP平台的实现有差异。在APP平台,我们可以使用本地路径(如从uni.chooseFile得到的路径)直接读取。 示例步骤: 1. 使用uni.chooseFile选择文件(或者给定一个路径)。 2. 调用uni.readFile读取文件为ArrayBuffer。 3. 将ArrayBuffer转为Uint8Array,然后遍历每个字节,将每个字节转为两个16进制字符(注意补零)。 但是,如果文件很大,我们不应该一次性读取整个文件,而是分块读取?但是uni.readFile是一次性读取。所以如果文件很大,可能会造成内存问题。因此,我们假设文件不会太大。 代码结构: - 选择文件 - 读取文件 - 处理ArrayBuffer:转换为16进制字符串 - 输出日志 详细日志:在控制台输出每个步骤的状态,以及关键数据(如文件大小、读取的字节数、转换后的前100个字节的16进制字符串等)。 下面是一个示例代码: </think> 以下是一个UniApp APP读取本地.bin文件(小端序)并解析为16进制数据的完整示例代码,包含详细日志输出: ```javascript // 文件选择与读取函数 async function readAndParseBinFile() { try { // 1. 用户选择文件 const [file] = await uni.chooseFile({ count: 1, type: 'file', extension: ['.bin'] }); console.log('[STEP 1] 文件选择完成', `文件名: ${file.name}, 路径: ${file.path}, 大小: ${file.size}字节`); // 2. 读取文件为ArrayBuffer const arrayBuffer = await uni.getFileSystemManager().readFile({ filePath: file.path, encoding: 'binary' // 重要:获取原始二进制数据 }); console.log('[STEP 2] 文件读取成功', `数据长度: ${arrayBuffer.byteLength}字节`); // 3. 转换为Uint8Array处理二进制 const uint8Array = new Uint8Array(arrayBuffer); console.log('[STEP 3] 二进制数据转换完成', `首字节: 0x${uint8Array[0].toString(16).padStart(2, '0')}`); // 4. 解析为16进制字符串(小端序处理) let hexString = ''; for (let i = 0; i < uint8Array.length; i++) { // 小端序:直接按字节顺序处理 hexString += uint8Array[i].toString(16).padStart(2, '0'); } console.log(`[STEP 4] HEX转换完成`, `总长度: ${hexString.length}字符, 样本: ${hexString.substring(0, 50)}...`); // 5. 按小端序解析多字节数值(示例:解析前4字节为32位整数) if (uint8Array.length >= 4) { const view = new DataView(arrayBuffer); const intValue = view.getUint32(0, true); // true表示小端序 console.log(`[STEP 5] 小端序解析示例`, `前4字节值: ${intValue} (0x${intValue.toString(16)})`); } return hexString; } catch (error) { console.error('[ERROR] 处理失败', error); throw new Error(`文件处理失败: ${error.message}`); } } // 调用示例 readAndParseBinFile().then(hexResult => { console.log('[FINAL] 解析结果', `前100字符: ${hexResult.substring(0, 100)}`); }).catch(err => { uni.showToast({ title: err.message, icon: 'none' }); }); ``` ### 关键代码解析 1. **文件选择与读取** - 使用`uni.chooseFile`获取用户选择的.bin文件路径 - 通过`getFileSystemManager().readFile`读取为ArrayBuffer - 日志输出文件基础信息(文件名、路径、大小)[^1] 2. **二进制处理** - 将ArrayBuffer转换为`Uint8Array`进行字节级操作 - 使用`toString(16)`将每个字节转为16进制字符串 - `padStart(2, '0')`确保单字节补零(如`0xF`→`0x0F`) 3. **小端序处理** - 字节顺序直接按数组顺序处理(小端序) - 使用`DataView`解析多字节数值(如32位整数) - `getUint32(0, true)`第二个参数`true`指定小端序[^3] 4. **日志输出设计** - 分步骤标记([STEP 1]-[STEP 5]) - 关键数据采样(首字节、前100字符) - 错误捕获和友好提示 ### 日志输出示例 ``` [STEP 1] 文件选择完成 文件名: data.bin, 路径: /storage/emulated/0/Download/data.bin, 大小: 1024字节 [STEP 2] 文件读取成功 数据长度: 1024字节 [STEP 3] 二进制数据转换完成 首字节: 0x4d [STEP 4] HEX转换完成 总长度: 2048字符, 样本: 4d5a00000100000040000000ff... [STEP 5] 小端序解析示例 前4字节值: 1549607553 (0x5a4d0000) [FINAL] 解析结果 前100字符: 4d5a00000100000040000000ff... ``` ### 注意事项 1. **小端序处理**:多字节数据需通过`DataView`指定小端序,单字节转换无需特殊处理 2. **性能优化**:大文件处理建议分块读取,避免内存溢出 3. **平台差异**:`uni.getFileSystemManager()`在Android/iOS均可用 4. **权限要求**:Android需在`manifest.json`添加`"permission": ["android.permission.READ_EXTERNAL_STORAGE"]`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值