鸿蒙开发中向模拟机应用沙箱路径中传入文件

简介

在刚开始学习鸿蒙开发前,只有c/c++的学习经验,对于移动端开发知识了解不多,所以在开发过程中遇到很多简单但不好解决的问题,下面就碰到一个认为比较麻烦的问题进行介绍,有不正之处,敬请指出。

文章写于2024年7月10日,使用的编译器的sdk如下图:

在这里插入图片描述

目录介绍

鸿蒙开发中,文件目录分为两类,一是用户文件目录,二是应用文件目录。具体介绍可参阅鸿蒙开发文档进项详细了解。要说明的是,有开发file kit 是只面向于应用文件,只能操作于沙箱路径,所以在调用fs的函数时,注意要写入沙箱路径。

向应用文件中传入文件

在网上搜索了一部份资料后,了解到有两种方法:

  1. 以命令行的方式,通过hdc命令的方式向沙箱路径中写入文件;
    在这里插入图片描述
    *说明
    在这里插入图片描述
    • 应用名称就是bundle-name ,在程序中可通过路径"\AppScope",打开配置文件"app.json5"查询;
    • “主Ability名称”是ability-name,在程序中可通过路径"\entry\src\main",打开配置文件”module.json5“,查询ability名称,如下图
      在这里插入图片描述
    • “可用端口号”为cmd的界面,输入 hdc list targets ,后面的端口号,即为可用端口号。
      成功之后 ,会依照提示successful,输入 ps -ef | grep bftpd,会出现pid号。
      后续可根据提示进行上传文件。

2.该方法是通过读取rawfile中的文件内容到ArrayBuffer,然后再写入到沙箱路径下的文件。至于为什么不用copyfile,好像在copy后,文件会出现乱码,所以才会有这么麻烦的做法,如果哪位仁兄通过了,可以提醒我一下。

具体内容:
1. 获取rawfile的文件描述符,用fs.read读出文件src中的内容,放入到ArrayBuffer中。

let buf = new ArrayBuffer(**size**);//此处size不宜太小,否则当要写入的文件过大时,会导致文件写入不完全,文件结构损坏
private context = getContext(this) as common.UIAbilityContext;
try {
  this.context.resourceManager.getRawFd("test.txt", (error: BusinessError, value: resourceManager.RawFileDescriptor) => {
    if (error != null) {
      console.error(`callback getRawFd failed error code: ${error.code}, message: ${error.message}.`);
    } else {
      let fd = value.fd;
      let offset = value.offset;
      let length = value.length;
      fs.read(fs, buf, {length:length, offset:offset});//此处read opeation中,要读取的长度跟读取的偏移量必须要写入,否则会出现乱码情况
    }
  });
} catch (error) {
  let code = (error as BusinessError).code;
  let message = (error as BusinessError).message;
  console.error(`callback getRawFd failed, error code: ${code}, message: ${message}.`);
}
  1. 在沙箱目录下新建一个文件dst,通过write把buf写入到文件当中。
//path为沙箱路径
let sss = fs.openSync(pdfPath,
 fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE | fs.OpenMode.TRUNC); //没有会创建一个空的input.txt
fs.write(file.fd, str , {{length:length, offset:0}}).then((writeLen: number) => {  //此处的offset为0,要从文件的开头开始写起
  console.info("write data to file succeed and size is:" + writeLen);
}).catch((err: BusinessError) => {
  console.error("write data to file failed with error message: " + err.message + ", error code: " + err.code);
}).finally(() => {
  fs.closeSync(file);
});

代码如下:粘贴后可直接成功运行,

import fs, { ConflictFiles } from '@ohos.file.fs';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@ohos.base';
import resourceManager from '@ohos.resourceManager';

@Entry
@Component
struct Index {
  @State new_File: string = '新建文件'
  @State write_File: string = '向文件中写入内容'
  private context = getContext(this) as common.UIAbilityContext;
  private applicationContext = this.context.getApplicationContext();
  private fileDir = this.applicationContext.filesDir;
  private dirPath = this.fileDir; 
  private filePath = this.dirPath + "/sample.pdf"

  build() {
    Row() {
      Column() {
        Button(this.new_File)
          .fontSize(25)
          .fontWeight(FontWeight.Normal)
          .backgroundColor(Color.Green)
          .onClick(() => {
            //新建文件,如果存在文件则提示已存在文件

            fs.access(this.filePath, (err: BusinessError, res: boolean) => {
              if (err) {
                console.error("access failed with error message: " + err.message + ", error code: " + err.code);
              } else {
                if (res) {
                  console.info("file exists");

                } else {
                  console.info("file not exists");
                  let f = fs.createStreamSync(this.filePath, "wr+");
                  f.closeSync();
                }
              }
            });

          })
        Button(this.write_File)
          .fontSize(25)
          .fontWeight(FontWeight.Normal)
          .backgroundColor(Color.Green)
          .onClick(() => {


            let file = fs.openSync(this.filePath, fs.OpenMode.READ_WRITE);
            let buf = new ArrayBuffer(99999999);
            try {
              this.context.resourceManager.getRawFd("sample.pdf")//获取文件的fd,rawfile下需要有文件存在
                .then((value: resourceManager.RawFileDescriptor) => {
                  let fd = value.fd;
                  let offset = value.offset;
                  let length = value.length;
                  console.info(`fd fd ${value.fd} offset ${value.offset} length ${value.length}`);

                  //读文件,
                  fs.read(fd, buf, { length: value.length, offset: value.offset });
                  console.info("buf", buf.byteLength);
                  //写文件
                  fs.write(file.fd, buf, { length: value.length, offset: 0 }).then((writeLen: number) => {
                    //fs.write(sss.fd, buf).then((writeLen: number) => {
                    console.info("write data to file succeed and size is:" + writeLen);
                  }).catch((err: BusinessError) => {
                    console.error("write data to file failed with error message: " + err.message + ", error code: " +
                    err.code);
                  }).finally(() => {
                    fs.closeSync(file);
                  });
                })
                .catch((error: BusinessError) => {
                  console.error(`promise getRawFd error error code: ${error.code}, message: ${error.message}.`);
                });
            } catch (error) {
              let code = (error as BusinessError).code;
              let message = (error as BusinessError).message;
              console.error(`promise getRawFd failed, error code: ${code}, message: ${message}.`);
            }
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

运行效果如下:
在这里插入图片描述
文件中的文件
在这里插入图片描述

点击新建文件后:此时文件大小还为0
在这里插入图片描述
点击向文件写入内容后:文件大小为248.4kb
在这里插入图片描述
在这里插入图片描述
可以正常显示。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值