HarmonyOS 媒体文件 C++ 访问的问题

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/select-user-file-V5

如何用标准 C++ 库访问媒体文件?参考这个文档,获取到的本地路径传给 C++ 层,访问不到

HarmonyOS
3天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
fox280
#include "napi/native_api.h"
#include <xxxtream>
#include <string>
#include "hilog/log.h"
#include <sys/stat.h>
#include <unistd.h>
  bool isFileExists(const std::string &filename) {
  return access(filename.c_str(), F_OK) == 0;
}

std::string stringFromValue(napi_env env, napi_value value) {
  size_t length = 0;
  napi_get_value_string_utf8(env, value, nullptr, 0, &length);
  std::string ret_str(length, '\0');
  napi_get_value_string_utf8(env, value, (char *)ret_str.data(), length + 1, &length);
  return ret_str;
}

static napi_value Add(napi_env env, napi_callback_info info) {
  size_t requireArgc = 2;
  size_t argc = 2;
  napi_value args[2] = {nullptr};

  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

  napi_valuetype valuetype0;
  napi_typeof(env, args[0], &valuetype0);

  napi_valuetype valuetype1;
  napi_typeof(env, args[1], &valuetype1);

  double value0;
  napi_get_value_double(env, args[0], &value0);

  double value1;
  napi_get_value_double(env, args[1], &value1);

  napi_value sum;
  napi_create_double(env, value0 + value1, &sum);

  return sum;
}

static napi_value NAPI_Global_sendImageMessage(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

std::string localPath = stringFromValue(env, args[0]);
int fd;
napi_get_value_int32(env, args[1], &fd);
struct stat statdata;
int state = fstat(fd, &statdata);
OH_LOG_Print(LOG_APP, LOG_INFO, 1, "IM-Native", "%{public}d %{public}d",fd,state);
OH_LOG_Print(LOG_APP, LOG_INFO, 1, "IM-Native", "%{public}d",statdata.st_size);
}

static napi_value NAPI_Global_sendSandboxImage(napi_env env, napi_callback_info info) {
  size_t argc = 1;
  napi_value args[1] = {nullptr};
  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

  std::string localPath = stringFromValue(env, args[0]);
  if (isFileExists(localPath)) {
    OH_LOG_Print(LOG_APP, LOG_INFO, 1, "IM-Native", "NAPI_Global_sendSandboxImage exist");
  } else {
    OH_LOG_Print(LOG_APP, LOG_INFO, 1, "IM-Native", "NAPI_Global_sendSandboxImage not exist");
  }
}
static napi_value NAPI_Global_sendSandboxFile(napi_env env, napi_callback_info info) {
  size_t argc = 1;
  napi_value args[1] = {nullptr};
  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

  std::string localPath = stringFromValue(env, args[0]);
  if (isFileExists(localPath)) {
    OH_LOG_Print(LOG_APP, LOG_INFO, 1, "IM-Native", "NAPI_Global_sendSandboxFile exist");
  } else {
    OH_LOG_Print(LOG_APP, LOG_INFO, 1, "IM-Native", "NAPI_Global_sendSandboxFile not exist");
  }
}
static napi_value NAPI_Global_sendFileMessage(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

std::string localPath = stringFromValue(env, args[0]);
int fd;
napi_get_value_int32(env, args[1], &fd);
struct stat statdata;
int state = fstat(fd, &statdata);
OH_LOG_Print(LOG_APP, LOG_INFO, 1, "IM-Native", "%{public}d %{public}d",fd,state);
OH_LOG_Print(LOG_APP, LOG_INFO, 1, "IM-Native", "%{public}d",statdata.st_size);
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
  napi_property_descriptor desc[] = {
    {"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr},
  {"sendSandboxImage", nullptr, NAPI_Global_sendSandboxImage, nullptr, nullptr, nullptr, napi_default, nullptr},
  {"sendImageMessage", nullptr, NAPI_Global_sendImageMessage, nullptr, nullptr, nullptr, napi_default, nullptr},
  {"sendSandboxFile", nullptr, NAPI_Global_sendSandboxFile, nullptr, nullptr, nullptr, napi_default, nullptr},
  {"sendFileMessage", nullptr, NAPI_Global_sendFileMessage, nullptr, nullptr, nullptr, napi_default, nullptr}};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END

static napi_module demoModule = {
  .nm_version = 1,
  .nm_flags = 0,
  .nm_filename = nullptr,
  .nm_register_func = Init,
  .nm_modname = "entry",
  .nm_priv = ((void *)0),
  .reserved = {0},
};

extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
export const add: (a: number, b: number) => number;

export const sendSandboxImage: (localPath: string) => void;

export const sendImageMessage: (localPath: string, fd: number) => void;

export const sendSandboxFile: (localPath: string) => void;

export const sendFileMessage: (localPath: string, fd: number) => void;
import testNapi from 'libentry.so';
import picker from '@ohos.file.picker';
import { BusinessError } from '@ohos.base';
import { FileUtil } from '../util/FileUtil';
import fileUri from "@ohos.file.fileuri";
import hilog from '@ohos.hilog';
import fs from '@ohos.file.fs';
import environment from '@ohos.file.environment';
@Entry
@Component
struct Index {
  @State message: string = '选择图片';

  aboutToAppear(): void {
    FileUtil.createFile(getContext(this));
    FileUtil.createImage(getContext(this));
  }

  build() {
    Row() {
      Column() {
        Button("发送沙盒图片").fontSize(25).fontWeight(FontWeight.Bold).onClick(() => {
          this.sendSandboxImage();
        })

        Button("选择相册图片并发送").fontSize(25).fontWeight(FontWeight.Bold).onClick(() => {
          this.chooseImage();
        })


        Button("发送沙盒文件").fontSize(25).fontWeight(FontWeight.Bold).onClick(() => {
          this.sendSandboxFile();
        })

        Button("选择手机文件并发送").fontSize(25).fontWeight(FontWeight.Bold).onClick(() => {
          this.chooseFile();
        })
      }.width('100%')
    }.height('100%')
  }

  private sendSandboxImage() {
    let localPath = FileUtil.getImagePath(getContext(this));
    hilog.info(0x0000, 'IM-ArkTs', "sendSandboxImage " + localPath);
    testNapi.sendSandboxImage(localPath);
  }

  private chooseImage() {
    const photoSelectOptions = new picker.PhotoSelectOptions();
    photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE
    photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目
    const photoViewPicker = new picker.PhotoViewPicker();
    photoViewPicker.select(photoSelectOptions).then((photoSelectResult: picker.PhotoSelectResult) => {
      let imageUris = photoSelectResult.photoUris;
      if (imageUris.length > 0) {
        let localPath = imageUris[0];
        hilog.info(0x0000, 'IM-ArkTs', "sendImageMessage " + localPath);
        // file://media/Photo/16/IMG_1718281435_015/IMG_20240613_202215.jpg
        let file = fs.openSync(localPath, fs.OpenMode.READ_ONLY);
        console.info('file fd: ' + file.fd);
        console.info('file fd: ' + file.path);
        console.info('file fd: ' + file.name);
        // /Photo/16/IMG_1718281435_015
        let file2 = fs.dup(file.fd);
        console.info("The name of the file2 is " + file2.name);
        console.info("The Path of the file2 is " + file2.path)
        hilog.info(0x0000, 'IM-ArkTs', "sendImageMessage " + localPath);
        testNapi.sendImageMessage(localPath, file.fd);
      }
    }).catch((err: BusinessError) => {
      console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
    })
  }

  private sendSandboxFile() {
    let localPath = FileUtil.getFilePath(getContext(this));
    //不能写这行代码,否则底层 C++ 访问不到该地址
    // /data/storage/el2/base/haps/entry/files/test.txt
    hilog.info(0x0000, 'IM-ArkTs', "sendSandboxFile " + localPath);
    testNapi.sendSandboxFile(localPath);
  }

  private chooseFile() {
    const documentSelectOptions = new picker.DocumentSelectOptions();
    documentSelectOptions.maxSelectNumber = 5; // 选择文档的最大数目(可选)
    documentSelectOptions.defaultFilePathUri = "file://docs/storage/Users/currentUser/test"; // 指定选择的文件或者目录路径(可选)
    documentSelectOptions.fileSuffixFilters = ['.png', '.txt', '.mp4']; // 选择文件的后缀类型,若选择项存在多个后缀名,则每一个后缀名之间用英文逗号进行分隔,而且后缀类型名不能超过100个(可选)。

    const documentViewPicker = new picker.DocumentViewPicker(); // 创建文件选择器实例
    documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => {
      let uris = documentSelectResult;
      if (uris.length > 0) {
        let localPath = uris[0];
        hilog.info(0x0000, 'IM-ArkTs', "sendImageMessage " + localPath);
        // file://docs/storage/Users/currentUser/fm7.txt
        let file = fs.openSync(localPath, fs.OpenMode.READ_ONLY);
        console.info('file fd: ' + file.fd);
        console.info('file fd: ' + file.path);
        console.info('file fd: ' + file.name);
        // /storage/Users/currentUser/fm7.txt
        let file2 = fs.dup(file.fd)
        console.info("The name of the file2 is " + file2.fd);
        console.info("The name of the file2 is " + file2.name);
        console.info("The Path of the file2 is " + file2.path)
        hilog.info(0x0000, 'IM-ArkTs', "sendFileMessage " + file.path);
        testNapi.sendFileMessage(localPath,file.fd);
      }
    }).catch((err: BusinessError) => {
      console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
    })
  }
}
分享
微博
QQ
微信
回复
3天前
相关问题
在读取媒体文件open: permission denied
2876浏览 • 1回复 待解决
ArkTS层通过接口访问C++层对象
371浏览 • 1回复 待解决
使用C++进行HarmonyOS开发问题
742浏览 • 2回复 待解决
c/c++层主动调用ArkTS存在问题
380浏览 • 1回复 待解决
HarmonyOS媒体资源访问方式
29浏览 • 1回复 待解决
基于HAR跨模块C++文件引用
856浏览 • 1回复 待解决
HarmonyOS ArkTS与C/C++交互
745浏览 • 1回复 待解决
如何修改C++版本?C++支持情况?
1160浏览 • 1回复 待解决
如何在C/C++ 创建ArkTS对象
2220浏览 • 1回复 待解决
HarmonyOS 媒体问题相关咨询
213浏览 • 1回复 待解决
HarmonyOS C++异步操作
358浏览 • 1回复 待解决
如何实现ArkTS与C/C++数组转换
752浏览 • 1回复 待解决