HarmonyOS 鸿蒙Next 应用迁移沙箱目录下无拷贝文件

发布于 1周前 作者 htzhanglong 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 应用迁移沙箱目录下无拷贝文件

import BackupExtensionAbility, { BundleVersion } from '@ohos.application.BackupExtensionAbility';
import { common, contextConstant } from '@kit.AbilityKit';
import { fileIo, ReadOptions } from '@kit.CoreFileKit';
import { relationalStore } from '@kit.ArkData';
import { UserBean, UserCenter } from 'bbt_user_center';
import { UserInfoBean } from 'bbt_user_center/src/main/ets/model/UserBean';
import { resourceManager } from '@kit.LocalizationKit';
import { AppConstants } from '../constants/Appconstants';
import { UTFileUtil, UTGlobalContext } from 'bbt_util';
import { fileIo as fs } from '@kit.CoreFileKit';
import { AppSdkUser } from '../module/sdk/AppSdkUser';

const TAG = `BackupExtensionAbility`;

// 实现终端设备从HarmonyOS 4.0升级到HarmonyOS NEXT后,应用数据的转换和迁移
export default class BackupExtension extends BackupExtensionAbility {
  onBackup() {
    console.log(TAG, `onBackup ok`);
  }

  /**
   * onRestore 接口是同步接口,其内部所有的异步操作请进行同步等待。
   */
  async onRestore(bundleVersion: BundleVersion): Promise<void> {
    console.log(TAG, `onRestore ok ${JSON.stringify(bundleVersion)}`);
    if (bundleVersion.name.startsWith("0.0.0.0")) {
      try {
        //备份
        this.context.area = contextConstant.AreaMode.EL2;
        //复制 安卓的db文件
        let sourceDbPath: string = this.context.backupDir + `restore/${AppConstants.ANDROID_PACKAGE_NAME}/ce/databases/`
        this.moveDbFile(this.context, sourceDbPath)
        //读取文件
        this.readFile(this.context)
      } catch (error) {
        console.log(TAG, `copyEl2Dirfail`);
      }
      console.log(TAG, `HarmonyOS to HarmonyOS NEXT scenario`);
    } else {
    }
  }

  /**
   * 移动双框架数据库文件到单框架
   * 文件参考@link FileTransferManager.moveFiles
   *
   * @param context context上下文
   * @return 成功返回true, 否则false
   */
  private async moveDbFile(context: common.Context, sourceDbPath: string): Promise<boolean> {
    try {
      console.log('应用迁移db文件拷贝', sourceDbPath)
      //检测文件是否存在
      if (!fs.accessSync(sourceDbPath)) {
        return false;
      }
      console.log('应用迁移db文件拷贝', '1')
      // 得到源路径下面所有的文件和目录
      let listFileNames: string[] = fs.listFileSync(sourceDbPath);
      if (!listFileNames || listFileNames.length === 0) {
        return false;
      }
      console.log('应用迁移db文件拷贝', '2')

      let srcPath = `${sourceDbPath}/b_user.db`;
      let destPath = context.filesDir + '/' + AppConstants.USERDB;
      if (fs.statSync(srcPath).isFile()) {
        fs.moveFileSync(srcPath, destPath);
        console.log('应用迁移db文件拷贝', '3')
      } else {
        fs.moveFileSync(srcPath, destPath);
        console.log('应用迁移db文件拷贝', '4')
      }
      return true;
    } catch (error) {
      console.log('应用迁移db文件拷贝', '5')
      // 异常处理逻辑,自行实现
      return false;
    }
  }

  public saveFileToCache(file: resourceManager.RawFileDescriptor, cFile: string) {
    // 创建缓存文件(当前是覆盖式创建)
    let cacheFile = fileIo.openSync(cFile, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
    // 读取缓冲区大小
    let bufferSize = 30000;
    let buffer = new ArrayBuffer(bufferSize); //创建buffer缓冲区

    // 要copy的文件的offset
    let currentOffset = file.offset;
    let readOption: ReadOptions = {
      offset: currentOffset, //期望读取文件的位置。可选,默认从当前位置开始读
      length: bufferSize //每次期望读取数据的长度。可选,默认缓冲区长度
    };
    // 后面len会一直减,直到没有
    while (true) {
      // 读取buffer容量的内容
      let readLength = fileIo.readSync(file.fd, buffer, readOption);
      console.log('readOption', readLength)
      // 写入buffer容量的内容
      fileIo.writeSync(cacheFile.fd, buffer, {
        length: readLength
      }); //写到cacheFile里
      // 判断后续内容 修改读文件的参数
      // buffer没读满代表文件读完了
      if (readLength < bufferSize) {
        break;
      }
      if (readOption.offset != undefined) {
        readOption.offset += readLength;
      }
    }
    console.log('Copy Success!!!')
    fileIo.close(cacheFile);
  }

  //读取文件
  readFile(context: common.Context) {
    try {
      //读取rawfile目录下db文件,value
      context.resourceManager.getRawFd(AppConstants.USERDB, (error, value) => {
        if (error != null) {
          console.log(`callback getRawFd failed error code: ${error.code}, message: ${error.message}`);
        } else {
          console.info(value.length.toString());
          let cFile = context.getApplicationContext().databaseDir + '/bbt_app_entry/rdb/' + AppConstants.USERDB;
          //覆盖并重新写入
          this.saveFileToCache(value, cFile)
        }
      });
    } catch (error) {
      console.error(`callback getRawFd failed, error code: ${error.code}, message: ${error.message}.`);
    }
  }
}

更多关于HarmonyOS 鸿蒙Next 应用迁移沙箱目录下无拷贝文件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

你好,请问下打印的日志都是正常的吗?参考的文档是哪个?

更多关于HarmonyOS 鸿蒙Next 应用迁移沙箱目录下无拷贝文件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对帖子标题“HarmonyOS 鸿蒙Next 应用迁移沙箱目录下无拷贝文件”的问题,以下是专业回答:

在HarmonyOS鸿蒙Next系统中,应用迁移沙箱目录是应用数据隔离和存储的重要机制。若在应用迁移过程中发现沙箱目录下无拷贝文件,可能是由于以下几个原因:

  1. 权限配置问题:确保应用已正确配置所需的数据访问权限,包括读写沙箱目录的权限。检查应用的manifest文件或相关权限配置,确保无误。

  2. 迁移策略错误:应用迁移过程中可能未正确执行文件拷贝操作。检查迁移逻辑,确保在迁移过程中正确地将文件从源目录拷贝到沙箱目录。

  3. 沙箱目录路径错误:确认沙箱目录的路径是否正确。路径错误可能导致文件无法正确拷贝到预期位置。

  4. 系统限制或Bug:在某些情况下,系统自身的限制或Bug可能导致文件迁移失败。此时,可尝试更新系统至最新版本,或关注华为官方发布的系统更新和修复信息。

若以上方法均无法解决问题,请考虑联系官网客服获取进一步帮助。官网地址是:https://www.itying.com/category-93-b0.html 。在此页面上,您可以找到客服联系方式并提交您的问题。

回到顶部