HarmonyOS 鸿蒙Next 从 rawfile 拷贝zip包到沙箱解压失败

发布于 1周前 作者 h691938207 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 从 rawfile 拷贝zip包到沙箱解压失败

期望:从 rawfile 拷贝zip包到沙箱解压成功,程序能正常访问。

尝试1:不用 zip,直接拷贝到沙箱,程序能正常访问。

尝试2:试图将文件换成 zip,拷贝到沙箱,然后解压文件,程序无法正常访问。

异常截图:

cke_5473.png
代码如下:

import { fileIo, ReadOptions } from '@kit.CoreFileKit';
import { resourceManager } from '@kit.LocalizationKit';
import { relationalStore } from '@kit.ArkData';
import fs from '@ohos.file.fs';
import { BusinessError, zlib } from '@kit.BasicServicesKit';

let context = getContext(this);
let rdbDirectory = context.getApplicationContext().databaseDir;
let rdbDirectoryDir = rdbDirectory + '/entry/rdb'
let resource = context.resourceManager;
let store: relationalStore.RdbStore | undefined = undefined
const STORE_CONFIG: relationalStore.StoreConfig = {
  name: 'Company.db',
  securityLevel: relationalStore.SecurityLevel.S1
};

/**
 * https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs-V5/faqs-local-database-management-12-V5
 * 如何读取本地/预制数据库
 */
export class CompanyDbUtils7 {

  saveFileToCache(file: resourceManager.RawFileDescriptor, dbName: string) {
    let fistPath = fs.listFileSync(rdbDirectoryDir)
    console.log("check dir file fistPath:"+ JSON.stringify(fistPath))
    // 创建缓存文件(当前是覆盖式创建)
    let cFile = rdbDirectoryDir +"/"+ dbName;
    console.log("cFile:"+cFile)
    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);
      // 写入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);
    let secondPath = fs.listFileSync(rdbDirectoryDir)
    console.log("check dir file secondPath:"+ JSON.stringify(secondPath))
    //对沙箱路径下的压缩文件进行解压
    try {
      zlib.decompressFile(rdbDirectoryDir+"/Company.zip", rdbDirectoryDir, (errData: BusinessError) => {
        if (errData !== null) {
          console.error(`decompressFile failed. code is ${errData.code}, message is ${errData.message}`);
          let dataBaseDirFileList = fs.listFileSync(rdbDirectoryDir)
          console.log("dataBaseDirFileList:"+ JSON.stringify(dataBaseDirFileList))
        }
      })
    } catch (errData) {
      let code = (errData as BusinessError).code;
      let message = (errData as BusinessError).message;
      console.error(`decompressFile failed. code is ${code}, message is ${message}`);
    }
    context.resourceManager.closeRawFd("Company.zip")
    let threePath = fs.listFileSync(rdbDirectoryDir)
    console.log("check dir file threePath:"+ JSON.stringify(threePath))
  }

  INIT() {
    //数据库名称
    let dbName: string = 'Company.zip';
    // 创建数据库沙箱目录
    try {
      //已经存在
      // if(fs.accessSync(rdbDirectoryDir + dbName)) {
      //   console.info("file exists");
      //   this.getRDB()
      //   return
      // }
      let dirPath = rdbDirectory + '/entry';
      fileIo.mkdirSync(dirPath);
      dirPath = dirPath + '/rdb';
      fileIo.mkdirSync(dirPath);
    } catch (error) {
      console.error(`mkdir rdbPath failed, error code: ${error.code}, message: ${error.message}.`);
    }
    //读取rawfile目录下db文件
    try {
      resource.getRawFd('rdb/' + dbName, (error, value) => {
        if (error != null) {
          console.log(`callback getRawFd failed error code: ${error.code}, message: ${error.message}.`);
        } else {
          console.info(value.length.toString());
          this.saveFileToCache(value, dbName);
          this.getRDB()
        }
      });
    } catch (error) {
      console.error(`callback getRawFd failed, error code: ${error.code}, message: ${error.message}.`);
    }
  }

  getRDB(): relationalStore.RdbStore | undefined {
    relationalStore.getRdbStore(context, STORE_CONFIG, (err, rdbStore) => {
      if (err) {
        console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
        return;
      } else {
        console.info(`Succeeded in getting RdbStore.`);
      }
      store = rdbStore
    })
    return store;
  }
}

let companyDbUtils = new CompanyDbUtils7();

export default companyDbUtils as CompanyDbUtils7;
2 回复

根据报错信息显示,可能原因:

1、当调用decompressFile接口时,传入的源文件压缩格式有误。 2、当调用decompressFile接口时,传入的源文件不完整或已损坏。 请参考如下文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-references/errorcode-zlib-0000001813576548#ZH-CN_TOPIC_0000001813576548__900003-传入的源文件格式错误或者已损坏

copy文件试下这个

let dest = fs.openSync(cFile, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
    let bufsize = 4096
    let buf = new ArrayBuffer(bufsize)
    let off = 0, len = 0, readedLen = 0 /* * 通过buffer将rawfile文件内容copy到沙箱路径 */
    while (len = fs.readSync(value.fd, buf, { offset: value.offset + off, length: bufsize })) {
      readedLen += len
      fs.writeSync(dest.fd, buf, { offset: off, length: len })
      off = off + len
      if ((value.length - readedLen) < bufsize) {
        bufsize = value.length - readedLen
      }
    }
    fs.close(dest.fd)<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

针对您提到的HarmonyOS鸿蒙Next系统中从rawfile拷贝zip包到沙箱解压失败的问题,可能涉及以下几个方面的原因及解决方案概述:

  1. 权限问题:确保您的应用或进程拥有足够的权限访问rawfile及沙箱目录。鸿蒙系统对文件访问有严格的安全控制,需检查并申请必要的权限。

  2. 路径或文件名问题:检查源文件路径和目标沙箱路径是否正确,以及文件名是否包含不支持的字符或过长。路径错误或文件名不合规可能导致拷贝失败。

  3. 文件系统差异:鸿蒙系统的文件系统可能与传统Android有所差异,确保zip包格式及解压工具兼容鸿蒙系统。

  4. 沙箱环境限制:沙箱环境可能对文件操作有特定限制,如大小限制、读写速度限制等,需确认这些限制是否影响解压操作。

  5. 系统Bug或版本问题:考虑是否为鸿蒙系统的已知问题或特定版本的bug,可查阅官方更新日志或社区反馈。

如果上述检查均无误,但问题依旧没法解决,请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。他们将提供更专业的技术支持和解决方案。

回到顶部