常见数据格式与ArrayBuffer的互相转换
=======================

#### 问题现象

ArrayBuffer是HarmonyOS开发中经常用到的数据类型，很多接口的入参都要求是ArrayBuffer，如何将一些常见的数据类型转换为ArrayBuffer类型？

#### 背景知识

*   [Base64Helper](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-util#base64helper9)：Base64Helper类提供Base64编解码和Base64URL编解码功能。
*   [TextEncoder](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-util#textencoder)：TextEncoder将字符串编码为字节数组，支持多种编码格式。

#### 解决方案

**Base64与ArrayBuffer互相转换**

Base64转ArrayBuffer：

_/\*\*_
 _\* 将Base64格式字符串转换为ArrayBuffer类型_
 _\* @param src Base64字符串_
 _\* @returns ArrayBuffer格式数据_
 _\*/_
public static base64ToArrayBuffer(src: string): ArrayBuffer {
  if (src.length \== 0) {
    return new ArrayBuffer(0);
  }
  let base64Helper \= new util.Base64Helper();
  let uint8Array \= base64Helper.decodeSync(src);
  return uint8Array.buffer as ArrayBuffer;
}

ArrayBuffer转Base64：

_/\*\*_
 _\* 将ArrayBuffer转换为Base64格式_
 _\* @param src ArrayBuffer数据_
 _\* @returns Base64格式字符串_
 _\*/_
public static arrayBufferToBase64(src: ArrayBuffer): string {
  if (src.byteLength \== 0) {
    return '';
  }
  _// 将ArrayBuffer转成string，再编码成base64_
  let textDecoder \= util.TextDecoder.create('utf-8');
  return textDecoder.decodeToString(new Uint8Array(src));
}

**string与ArrayBuffer的互相转换**

string转ArrayBuffer：

_/\*\*_
 _\* 将字符串转换为ArrayBuffer格式_
 _\* @param src 字符串_
 _\* @returns ArrayBuffer格式数据_
 _\*/_
public static stringToArrayBuffer(src: string): ArrayBuffer {
  if (src.length \== 0) {
    return new ArrayBuffer(0);
  }
  let textEncoder \= util.TextEncoder.create('UTF-8');
  const uint8Array \= textEncoder.encodeInto(src);
  return uint8Array.buffer as ArrayBuffer;
}

ArrayBuffer转string：

_/\*\*_
 _\* 将ArrayBuffer格式转换为字符串_
 _\* @param src ArrayBuffer格式数据_
 _\* @returns 字符串_
 _\*/_
public static arrayBufferToString(src: ArrayBuffer): string {
  let textDecoder \= util.TextDecoder.create('UTF-8');
  let uint8Array \= new Uint8Array(src);
  return textDecoder.decodeToString(uint8Array);
}

**collections.ArrayBuffer与ArrayBuffer的互相转换**

collections.ArrayBuffer转ArrayBuffer：

_/\*\*_
 _\* 将collections.ArrayBuffer格式数据转换为ArrayBuffer_
 _\* @param src collections.ArrayBuffer格式数据_
 _\* @returns ArrayBuffer格式数据_
 _\*/_
public static CollectionsArrayBufferToArrayBuffer(src: collections.ArrayBuffer): ArrayBuffer {
  if (src.byteLength \== 0) {
    return new ArrayBuffer(0);
  }
  let collectionsUint8Array \= new collections.Uint8Array(src);
  let uint8Array \= new Uint8Array(collectionsUint8Array);
  return uint8Array.buffer as ArrayBuffer;
}

ArrayBuffer转collections.ArrayBuffer：

_/\*\*_
 _\* 将ArrayBuffer格式数据转换为collections.ArrayBuffer_
 _\* @param src ArrayBuffer格式数据_
 _\* @returns collections.ArrayBuffer格式数据_
 _\*/_
public static ArrayBufferToCollectionsArrayBuffer(src: ArrayBuffer): collections.ArrayBuffer {
  if (src.byteLength \== 0) {
    return new collections.ArrayBuffer(0);
  }
  let uint8Array: Uint8Array \= new Uint8Array(src);
  let collectionsUint8Array: collections.Uint8Array \= new collections.Uint8Array(uint8Array);
  return collectionsUint8Array.buffer as collections.ArrayBuffer;
}

完整代码及测试样例如下：

pages/Index.ets：

import { StringUtil, Base64Util, CollectionsArrayBufferUtil } from '../utils/ArrayBufferUtil';
import { collections } from '@kit.ArkTS';

@Entry
@Component
struct Index {
  build() {
    Column() {
      Button('Base64与Arraybuffer互相转换')
        .onClick(() \=\> {
          let base64 \= 'SGVsbG8gSGFybW9ueU9TLCBIZWxsbyBXb3JsZC4=';
          let ret: ArrayBuffer \= Base64Util.base64ToArrayBuffer(base64);
          let uint8Array \= new Uint8Array(ret);
          console.info(uint8Array.toString());

          base64 \= Base64Util.arrayBufferToBase64(ret);
          console.info(base64);
        })
        .margin({
          bottom: 20
        });

      Button('string和ArrayBuffer互相转换')
        .onClick(() \=\> {
          let str \= 'Hello HarmonyOS, Hello World.';
          let ret: ArrayBuffer \= StringUtil.stringToArrayBuffer(str);
          let uint8Array \= new Uint8Array(ret);
          console.info(uint8Array.toString());

          str \= StringUtil.arrayBufferToString(ret);
          console.info(str);
        })
        .margin({
          bottom: 20
        });

      Button('collections.ArrayBuffer与ArrayBuffer互相转换')
        .onClick(() \=\> {
          let array \=
            \[72, 101, 108, 108, 111, 32, 72, 97, 114, 109, 111, 110, 121, 79, 83, 44, 32, 72, 101, 108, 108, 111, 32,
              87, 111, 114, 108, 100, 46\];
          let collectionsArrayBuffer \= new collections.Uint8Array(array).buffer;
          let ret: ArrayBuffer \= CollectionsArrayBufferUtil.CollectionsArrayBufferToArrayBuffer(collectionsArrayBuffer);
          let uint8Array \= new Uint8Array(ret);
          console.info(uint8Array.toString());

          collectionsArrayBuffer \= CollectionsArrayBufferUtil.ArrayBufferToCollectionsArrayBuffer(ret);
          console.info(\`collectionsArrayBuffer.byteLength: ${collectionsArrayBuffer.byteLength}\`);
        });
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center);
  }
}

utils/ArrayBufferUtil.ets：

import { collections, util } from '@kit.ArkTS';

_/\*\*_
 _\* 提供Base64格式数据与ArrayBuffer的互相转换能力_
 _\*/_
export class Base64Util {
  _/\*\*_
   _\* 将Base64格式字符串转换为ArrayBuffer类型_
   _\* @param src Base64字符串_
   _\* @returns ArrayBuffer格式数据_
   _\*/_
  public static base64ToArrayBuffer(src: string): ArrayBuffer {
    if (src.length \== 0) {
      return new ArrayBuffer(0);
    }
    let base64Helper \= new util.Base64Helper();
    let uint8Array \= base64Helper.decodeSync(src);
    return uint8Array.buffer as ArrayBuffer;
  }

  _/\*\*_
   _\* 将ArrayBuffer转换为Base64格式_
   _\* @param src ArrayBuffer数据_
   _\* @returns Base64格式字符串_
   _\*/_
  public static arrayBufferToBase64(src: ArrayBuffer): string {
    if (src.byteLength \== 0) {
      return '';
    }
    _//_ _将ArrayBuffer转成string，再编码成base64_
    let textDecoder \= util.TextDecoder.create('utf-8');
    return textDecoder.decodeToString(new Uint8Array(src));
  }

}
;

_/\*\*_
 _\* 提供string格式数据与ArrayBuffer的互相转换能力_
 _\*/_
export class StringUtil {
  _/\*\*_
   _\* 将字符串转换为ArrayBuffer格式_
   _\* @param src 字符串_
   _\* @returns ArrayBuffer格式数据_
   _\*/_
  public static stringToArrayBuffer(src: string): ArrayBuffer {
    if (src.length \== 0) {
      return new ArrayBuffer(0);
    }
    let textEncoder \= util.TextEncoder.create('UTF-8');
    const uint8Array \= textEncoder.encodeInto(src);
    return uint8Array.buffer as ArrayBuffer;
  }

 _ /\*\*_
   _\* 将ArrayBuffer格式转换为字符串_
   _\* @param src ArrayBuffer格式数据_
   _\* @returns 字符串_
   _\*/_
  public static arrayBufferToString(src: ArrayBuffer): string {
    let textDecoder \= util.TextDecoder.create('UTF-8');
    let uint8Array \= new Uint8Array(src);
    return textDecoder.decodeToString(uint8Array);
  }

}

_/\*\*_
 _\* 提供collections.ArrayBuffer格式数据与ArrayBuffer的互相转换能力_
 _\*/_
export class CollectionsArrayBufferUtil {
  _/\*\*_
   _\* 将collections.ArrayBuffer格式数据转换为ArrayBuffer_
   _\* @param src collections.ArrayBuffer格式数据_
   _\* @returns ArrayBuffer格式数据_
   _\*/_
  public static CollectionsArrayBufferToArrayBuffer(src: collections.ArrayBuffer): ArrayBuffer {
    if (src.byteLength \== 0) {
      return new ArrayBuffer(0);
    }
    let collectionsUint8Array \= new collections.Uint8Array(src);
    let uint8Array \= new Uint8Array(collectionsUint8Array);
    return uint8Array.buffer as ArrayBuffer;
  }

  _/\*\*_
   _\* 将ArrayBuffer格式数据转换为collections.ArrayBuffer_
   _\* @param src ArrayBuffer格式数据_
   _\* @returns collections.ArrayBuffer格式数据_
   _\*/_
  public static ArrayBufferToCollectionsArrayBuffer(src: ArrayBuffer): collections.ArrayBuffer {
    if (src.byteLength \== 0) {
      return new collections.ArrayBuffer(0);
    }
    let uint8Array: Uint8Array \= new Uint8Array(src);
    let collectionsUint8Array: collections.Uint8Array \= new collections.Uint8Array(uint8Array);
    return collectionsUint8Array.buffer as collections.ArrayBuffer;
  }

}