文档管理中心
我的

您当前正在浏览新版开发者文档中心,目录分类和层级有所调整。点击左侧当前文档分类名称前的“☰”图标,可切换文档分类。 了解新版目录

指南应用服务Preview Kit(文件预览服务)通用文件缓存加速(C/C++)

通用文件缓存加速(C/C++)

从6.1.0(23)版本开始,新增通用文件缓存加速功能。提供了缓存机制将文件的解码数据缓存到磁盘中,后续用户再次打开或浏览该文件,应用无需执行解码流程,可直接从磁盘中获取缓存的解码数据,省去耗时的解码时间。

接口说明

具体API说明详见API参考。

表1 文件缓存接口介绍

展开
接口名 描述
bool HMS_Preview_FileCacheBoost_IsSupported (void) 查询当前设备是否支持文件缓存加速功能。建议使用本接口检查,确认设备支持文件缓存加速功能后,再使用其他文件缓存加速接口如HMS_FileCacheBoost_Init等。

FileCacheBoost_ErrCode HMS_FileCacheBoost_Init (

const char* path, size_t pathLen, uint32_t cacheUpperLimitMb, const char* dbName, size_t dbNameLen)

初始化缓存路径、缓存容量上限、数据库名称。系统保证了线程并发安全控制,如需支持多进程并发场景,建议各进程使用不同的数据库文件名以保证访问安全性。

FileCacheBoost_ErrCode HMS_FileCacheBoost_AddObjectByKey (

const uint8_t *key, size_t keyLen, const uint8_t *data, size_t dataLen, uint32_t weight)

向系统添加缓存。计算的key为缓存的唯一标识。用户可传入缓存的权重,系统会参考该权重计算缓存的优先级进行容量管理,若开发者希望某个缓存对象优先保留,应为其分配较高的权重。

FileCacheBoost_ErrCode HMS_FileCacheBoost_GetObjectByKey (

const uint8_t *key, size_t keyLen, uint8_t **data, size_t *dataLen)

根据key值获取对应的缓存。
FileCacheBoost_ErrCode HMS_FileCacheBoost_RemoveObjectByKey (const uint8_t *key, size_t keyLen) 根据key值删除对应的缓存。
FileCacheBoost_ErrCode HMS_FileCacheBoost_ClearAllCache (void) 删除当前所有的缓存。
FileCacheBoost_ErrCode HMS_FileCacheBoost_AddSerialObjectByKey (const uint8_t *key, size_t keyLen, SerializeFunc func, const void *object, uint32_t weight) 创建一个复杂类型对象的缓存项,通过传入自定义的序列化函数SerializeFunc对该象进行序列化处理,以便将其存储至磁盘并支持后续恢复。
FileCacheBoost_ErrCode HMS_FileCacheBoost_GetSerialObjectByKey (const uint8_t *key, size_t keyLen, DeserializeFunc func, void **object) 根据指定的key值从缓存中获取复杂类型对象,并通过传入的反序列化函数DeserializeFunc将其还原为原始数据,从而获得完整的对象内容。

约束限制

支持的设备类型:PC/2in1,从26.0.0版本开始,新增支持tablet设备。

开发步骤

  1. 添加对应的头文件。

    收起
    自动换行
    深色代码主题
    复制
    1. #include "PreviewKit/file_cache_boost.h"
    2. #include <string>
  2. 编写CMakeLists.txt,新增对通用文件缓存功能的依赖。

    收起
    自动换行
    深色代码主题
    复制
    1. find_library(
    2. FILE_CACHE_BOOST
    3. NAMES libfile_cache_boost.so
    4. PATHS ${CMAKE_FIND_ROOT_PATH}/lib/aarch64-linux-ohos
    5. )
    6. # ...
    7. target_link_libraries(entry PUBLIC ${FILE_CACHE_BOOST})
  3. 初始化操作,开发者可初始化缓存路径、缓存容量上限、数据库名称,系统会创建缓存路径和对应的数据库。

    收起
    自动换行
    深色代码主题
    复制
    1. napi_value OH_Init(napi_env env, napi_callback_info info) {
    2. // 获取参数数量
    3. size_t argc = 2; // 需要2个参数:path和cacheUpperLimitMb
    4. napi_value args[2];
    5. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    6. // 检查参数数量
    7. if (argc < 2) {
    8. napi_throw_error(env, nullptr, "Invalid number of arguments");
    9. return nullptr;
    10. }
    11. // 获取path
    12. size_t pathLen;
    13. char *path;
    14. napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &pathLen);
    15. if (status != napi_ok) {
    16. napi_throw_error(env, nullptr, "Failed to get path length");
    17. return nullptr;
    18. }
    19. // 分配内存并获取path的内容
    20. path = new char[pathLen + 1];
    21. napi_get_value_string_utf8(env, args[0], path, pathLen + 1, &pathLen);
    22. // 获取cacheUpperLimitMb
    23. uint32_t cacheUpperLimitMb;
    24. napi_get_value_uint32(env, args[1], &cacheUpperLimitMb);
    25. // 设置固定的dbName参数
    26. const char *dbName = "hwcache"; // 硬编码数据库名称
    27. int32_t dbNameLen = static_cast<int32_t>(strlen(dbName));
    28. // path开发者可传入一个相对路径,如"ohcache",cacheUpperLimitMb以MB为单位,2GB = 2048MB
    29. int result = HMS_FileCacheBoost_Init(path, pathLen, cacheUpperLimitMb, dbName, dbNameLen);
    30. if (result != FILE_CACHE_BOOST_SUCCESS) {
    31. // 初始化失败,开发者可自定义错误处理
    32. }
    33. // 释放path的内存
    34. delete[] path;
    35. // 将result转换为napi_value
    36. napi_value jsResult;
    37. napi_create_int32(env, result, &jsResult);
    38. return jsResult;
    39. }
  4. 初始化完成后,开发者可实现添加缓存操作,将需要的缓存数据落盘,下次使用时直接获取缓存数据。

    收起
    自动换行
    深色代码主题
    复制
    1. napi_value OH_AddObjectByKey(napi_env env, napi_callback_info info) {
    2. // 获取参数数量
    3. size_t argc = 3;
    4. napi_value args[3];
    5. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    6. // 检查参数数量
    7. if (argc < 3) {
    8. napi_throw_error(env, nullptr, "Invalid number of arguments");
    9. return nullptr;
    10. }
    11. // 获取key
    12. size_t keyLen;
    13. size_t fillStrLen;
    14. uint8_t *key = GetStringArg(env, args[0], keyLen);
    15. // 获取填充字符串
    16. uint8_t *fillStr = GetStringArg(env, args[1], fillStrLen);
    17. if (!key || !fillStr) {
    18. delete[] key;
    19. delete[] fillStr;
    20. napi_throw_error(env, nullptr, "Key or fill string is empty");
    21. return nullptr;
    22. }
    23. // 获取内存大小
    24. uint32_t bufferMB;
    25. napi_get_value_uint32(env, args[2], &bufferMB);
    26. // 计算内存大小
    27. size_t bufferLen = static_cast<size_t>(bufferMB) * 1024 * 1024;
    28. // 分配内存
    29. uint8_t *buffer = new uint8_t[bufferLen];
    30. // 用填充字符串填充内存
    31. for (size_t i = 0; i < bufferLen; i++) {
    32. buffer[i] = fillStr[i % fillStrLen]; // 用填充字符串循环填充
    33. }
    34. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "add Get Key is : %{public}s, KeyLen: %{public}zu", key,
    35. keyLen);
    36. uint32_t weight = 0;
    37. int result = isEableCancel
    38. ? ExecuteAddWithCancel(key, keyLen, buffer, bufferLen, weight)
    39. : HMS_FileCacheBoost_AddObjectByKey(key, keyLen, buffer, bufferLen, weight);
    40. v1.push_back(*key);
    41. delete[] key;
    42. delete[] fillStr;
    43. delete[] buffer;
    44. napi_value jsResult;
    45. napi_create_int32(env, result, &jsResult);
    46. return jsResult;
    47. }
  5. 添加缓存完成后,开发者使用时调用HMS_FileCacheBoost_GetObjectByKey直接获取缓存数据。

    收起
    自动换行
    深色代码主题
    复制
    1. napi_value OH_GetObjectByKey(napi_env env, napi_callback_info info) {
    2. // 获取参数数量
    3. size_t argc = 1;
    4. napi_value args[1];
    5. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    6. // 检查参数数量
    7. if (argc < 1) {
    8. napi_throw_error(env, nullptr, "Invalid number of arguments");
    9. return nullptr;
    10. }
    11. // 获取key和keyLen
    12. size_t keyLen;
    13. char *key;
    14. napi_get_value_string_utf8(env, args[0], nullptr, 0, &keyLen);
    15. key = new char[keyLen + 1];
    16. napi_get_value_string_utf8(env, args[0], key, keyLen + 1, &keyLen);
    17. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "Get Key is : %{public}s", key);
    18. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "Get KeyLen is : %{public}zu", keyLen);
    19. uint8_t *data = new uint8_t[500];
    20. size_t dataLen = 0;
    21. // 调用HMS_FileCacheBoost_GetObjectByKey
    22. int result = HMS_FileCacheBoost_GetObjectByKey(reinterpret_cast<uint8_t *>(key), keyLen, &data, &dataLen);
    23. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "Data length: %{public}zu", dataLen);
    24. if (result != FILE_CACHE_BOOST_SUCCESS) {
    25. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "key is no exits!");
    26. HMS_FileCacheBoost_FreeObject(data);
    27. delete[] key;
    28. napi_value jsResult;
    29. napi_create_int32(env, result, &jsResult);
    30. return jsResult;
    31. }
    32. if (data == nullptr || dataLen == 0) {
    33. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "get object fail! and Data length: %{public}zu", dataLen);
    34. HMS_FileCacheBoost_FreeObject(data);
    35. delete[] key;
    36. napi_value jsResult;
    37. napi_create_int32(env, result, &jsResult);
    38. return jsResult;
    39. }
    40. size_t printLen = std::min(dataLen, static_cast<size_t>(100));
    41. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "First 100 bytes of data:");
    42. for (size_t i = 0; i < printLen; ++i) {
    43. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "Byte[%{public}zu]: %{public}c", i, data[i]);
    44. }
    45. HMS_FileCacheBoost_FreeObject(data);
    46. delete[] key;
    47. napi_value jsResult;
    48. napi_create_int32(env, result, &jsResult);
    49. return jsResult;
    50. }
  6. 如果开发者需要删除不需要再使用的缓存,可以调用HMS_FileCacheBoost_RemoveObjectByKey。

    收起
    自动换行
    深色代码主题
    复制
    1. napi_value OH_RemoveObjectByKey(napi_env env, napi_callback_info info) {
    2. // 获取参数数量
    3. size_t argc = 1; // 只需要一个参数:key
    4. napi_value args[1];
    5. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    6. // 检查参数数量
    7. if (argc < 1) {
    8. napi_throw_error(env, nullptr, "Invalid number of arguments");
    9. return nullptr;
    10. }
    11. // 获取key
    12. napi_value keyArg = args[0];
    13. // 获取key的字符串信息
    14. size_t keyLen;
    15. napi_get_value_string_utf8(env, keyArg, nullptr, 0, &keyLen); // 获取key的长度
    16. // 分配缓冲区并获取key的内容
    17. char *keyData = new char[keyLen + 1];
    18. napi_get_value_string_utf8(env, keyArg, keyData, keyLen + 1, &keyLen);
    19. // 调用HMS_FileCacheBoost_RemoveObjectByKey,删除缓存
    20. int result = HMS_FileCacheBoost_RemoveObjectByKey(reinterpret_cast<uint8_t *>(keyData), keyLen);
    21. // 新增key不存在的返回值
    22. if (result != FILE_CACHE_BOOST_SUCCESS) {
    23. // 删除失败,开发者可自定义错误处理
    24. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "RemoveObjectByKey error");
    25. }
    26. // 释放缓冲区
    27. delete[] keyData;
    28. // 返回结果
    29. napi_value jsResult;
    30. napi_create_int32(env, result, &jsResult);
    31. return jsResult;
    32. }
  7. 如果开发者需要清除所有缓存,可以调用HMS_FileCacheBoost_ClearAllCache。

    收起
    自动换行
    深色代码主题
    复制
    1. napi_value OH_ClearAllCache(napi_env env, napi_callback_info info) {
    2. int result = HMS_FileCacheBoost_ClearAllCache();
    3. // 返回结果
    4. napi_value jsResult;
    5. napi_create_int32(env, result, &jsResult);
    6. return jsResult;
    7. }
  8. 当一个线程尝试删除数据对象的同时,有其他线程对其进行HMS_FileCacheBoost_AddObjectByKey操作, 调用HMS_FileCacheBoost_CancelOngoingIOByKey取消key对应的缓存对象当前正在进行的I/O操作。

    收起
    自动换行
    深色代码主题
    复制
    1. napi_value OH_CancelAllOperation(napi_env env, napi_callback_info info) {
    2. // 获取参数数量
    3. size_t argc = 1; // 只需要一个参数:key
    4. napi_value args[1];
    5. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    6. // 检查参数数量
    7. if (argc < 1) {
    8. napi_throw_error(env, nullptr, "Invalid number of arguments");
    9. return nullptr;
    10. }
    11. // 获取key的字符串信息
    12. size_t keyLen;
    13. napi_get_value_string_utf8(env, args[0], nullptr, 0, &keyLen); // 获取key的长度
    14. // 分配缓冲区并获取key的内容
    15. uint8_t *keyData = new uint8_t[keyLen + 1];
    16. napi_get_value_string_utf8(env, args[0], reinterpret_cast<char *>(keyData), keyLen + 1, &keyLen);
    17. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "OH_CancelAllOperation keyArg: %{public}s",
    18. reinterpret_cast<uint8_t *>(keyData));
    19. // 调用HMS_FileCacheBoost_CancelOngoingIOByKey
    20. int result =
    21. HMS_FileCacheBoost_CancelOngoingIOByKey(reinterpret_cast<uint8_t *>(keyData), static_cast<size_t>(keyLen));
    22. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "OH_CancelAllOperation result: %{public}d", result);
    23. delete[] keyData;
    24. // 返回结果
    25. napi_value jsResult;
    26. napi_create_int32(env, result, &jsResult);
    27. return jsResult;
    28. }
  9. 如果缓存数据依附于一个复杂类的对象,该类中可能包含其他复杂对象数据结构、指针等不可控数据,不一并保存,落盘后无法恢复。对于这种复杂类型数据,需要开发者提供序列化函数。

    收起
    自动换行
    深色代码主题
    复制
    1. // 序列化函数:将ImageData对象序列化为字节流
    2. FileCacheBoost_CbErrCode Serialize(const void *object, WriteFunc write, struct CacheKey *key) {
    3. // 1. 参数校验
    4. if (object == nullptr || write == nullptr || key == nullptr) {
    5. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "Serialize: invalid parameters!");
    6. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    7. }
    8. const struct ImageData* img = static_cast<const struct ImageData*>(object);
    9. // 2. 数据有效性检查
    10. if (img->width == 0 || img->height == 0 || img->pixels == nullptr) {
    11. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG,
    12. "Serialize: invalid image data! width=%{public}u, height=%{public}u",
    13. img->width, img->height);
    14. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    15. }
    16. // 3. 计算数据大小
    17. size_t metaDataSize = sizeof(uint32_t) * 2; // width + height
    18. size_t imageSize = img->width * img->height * sizeof(uint8_t);
    19. size_t totalSize = metaDataSize + imageSize;
    20. // 4. 分配缓冲区(一次写入策略,性能优化)
    21. uint8_t *buffer = new (std::nothrow) uint8_t[totalSize];
    22. if (buffer == nullptr) {
    23. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG,
    24. "Serialize: memory allocation failed! size=%{public}zu", totalSize);
    25. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    26. }
    27. // 5. 填充元数据(小端序)
    28. uint8_t *ptr = buffer;
    29. // 写入width(4字节,小端序)
    30. *ptr++ = static_cast<uint8_t>(img->width & 0xFF);
    31. *ptr++ = static_cast<uint8_t>((img->width >> 8) & 0xFF);
    32. *ptr++ = static_cast<uint8_t>((img->width >> 16) & 0xFF);
    33. *ptr++ = static_cast<uint8_t>((img->width >> 24) & 0xFF);
    34. // 写入height(4字节,小端序)
    35. *ptr++ = static_cast<uint8_t>(img->height & 0xFF);
    36. *ptr++ = static_cast<uint8_t>((img->height >> 8) & 0xFF);
    37. *ptr++ = static_cast<uint8_t>((img->height >> 16) & 0xFF);
    38. *ptr++ = static_cast<uint8_t>((img->height >> 24) & 0xFF);
    39. // 6. 复制像素数据
    40. std::copy(img->pixels, img->pixels + imageSize, ptr);
    41. // 7. 一次性写入所有数据(性能优化)
    42. FileCacheBoost_ErrCode errorCode = write(buffer, totalSize, key);
    43. // 8. 释放缓冲区
    44. delete[] buffer;
    45. if (errorCode == FILE_CACHE_BOOST_SUCCESS) {
    46. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG,
    47. "Serialize success! width=%{public}u, height=%{public}u, size=%{public}zu",
    48. img->width, img->height, totalSize);
    49. return FILE_CACHE_BOOST_CALLBACK_SUCCESS;
    50. } else {
    51. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG,
    52. "Serialize: write failed! errorCode=%{public}d", errorCode);
    53. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    54. }
    55. }
  10. 调用HMS_FileCacheBoost_AddSerialObjectByKey添加复杂数据的序列化缓存。

    收起
    自动换行
    深色代码主题
    复制
    1. napi_value OH_AddSerialObjectByKey(napi_env env, napi_callback_info info) {
    2. size_t argc = 3;
    3. napi_value args[3];
    4. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    5. // 检查参数数量
    6. if (argc < 3) {
    7. napi_throw_error(env, nullptr, "Invalid number of arguments");
    8. return nullptr;
    9. }
    10. // 获取key
    11. char* key1;
    12. size_t keyLen;
    13. napi_get_value_string_utf8(env, args[0], nullptr, 0, &keyLen);
    14. key1 = new char[keyLen + 1];
    15. napi_get_value_string_utf8(env, args[0], key1, keyLen + 1, &keyLen);
    16. // 获取width和height(作为字符串接收,然后转换为数字)
    17. char* widthStr = nullptr;
    18. size_t widthStrLen = 0;
    19. napi_get_value_string_utf8(env, args[1], nullptr, 0, &widthStrLen);
    20. widthStr = new char[widthStrLen + 1];
    21. napi_get_value_string_utf8(env, args[1], widthStr, widthStrLen + 1, &widthStrLen);
    22. uint32_t width = static_cast<uint32_t>(atoi(widthStr));
    23. char* heightStr = nullptr;
    24. size_t heightStrLen = 0;
    25. napi_get_value_string_utf8(env, args[2], nullptr, 0, &heightStrLen);
    26. heightStr = new char[heightStrLen + 1];
    27. napi_get_value_string_utf8(env, args[2], heightStr, heightStrLen + 1, &heightStrLen);
    28. uint32_t height = static_cast<uint32_t>(atoi(heightStr));
    29. // 构造ImageData对象
    30. struct ImageData* img = new (std::nothrow) ImageData();
    31. if (img == nullptr) {
    32. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "OH_AddSerialObjectByKey: ImageData allocation failed!");
    33. delete[] widthStr;
    34. delete[] heightStr;
    35. delete[] key1;
    36. napi_value jsResult;
    37. napi_create_int32(env, FILE_CACHE_BOOST_ERROR_NOMEM, &jsResult);
    38. return jsResult;
    39. }
    40. img->width = width;
    41. img->height = height;
    42. img->pixels = new (std::nothrow) uint8_t[width * height];
    43. if (img->pixels == nullptr) {
    44. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "OH_AddSerialObjectByKey: pixels allocation failed!");
    45. delete img;
    46. delete[] widthStr;
    47. delete[] heightStr;
    48. delete[] key1;
    49. napi_value jsResult;
    50. napi_create_int32(env, FILE_CACHE_BOOST_ERROR_NOMEM, &jsResult);
    51. return jsResult;
    52. }
    53. // 填充测试数据('a', 'b', 'c'循环)
    54. for (size_t i = 0; i < width * height; i++) {
    55. img->pixels[i] = 'a' + (i % 3);
    56. }
    57. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG,
    58. "HMS_FileCacheBoost_AddSerialObjectByKey: key=%{public}s, width=%{public}u, height=%{public}u",
    59. key1, width, height);
    60. uint32_t weight = 100;
    61. // 添加复杂类数据缓存
    62. int result = HMS_FileCacheBoost_AddSerialObjectByKey(
    63. reinterpret_cast<uint8_t*>(key1), keyLen, Serialize, img, weight
    64. );
    65. // 释放临时对象(数据已序列化到缓存)
    66. delete[] img->pixels;
    67. delete img;
    68. // 将result转换为napi_value
    69. napi_value jsResult;
    70. napi_create_int32(env, result, &jsResult);
    71. delete[] widthStr;
    72. delete[] heightStr;
    73. delete[] key1;
    74. return jsResult;
    75. }
  11. 对于使用序列化缓存的数据,获取时需要开发者提供反序列化函数。

    收起
    自动换行
    深色代码主题
    复制
    1. // 反序列化函数:从字节流恢复ImageData对象
    2. FileCacheBoost_CbErrCode Deserialize(void **object, ReadFunc read, struct CacheKey *key) {
    3. // 1. 参数校验
    4. if (object == nullptr || read == nullptr || key == nullptr) {
    5. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "Deserialize: invalid parameters!");
    6. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    7. }
    8. // 2. 读取元数据头部(8字节:width + height)
    9. uint8_t header[8];
    10. size_t headerSize = 8;
    11. FileCacheBoost_ErrCode errorCode = read(header, &headerSize, key);
    12. if (errorCode != FILE_CACHE_BOOST_SUCCESS || headerSize != 8) {
    13. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG,
    14. "Deserialize: read header failed! errorCode=%{public}d, size=%{public}zu",
    15. errorCode, headerSize);
    16. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    17. }
    18. // 3. 解析元数据(小端序)
    19. uint32_t width = static_cast<uint32_t>(
    20. header[0] | (header[1] << 8) | (header[2] << 16) | (header[3] << 24)
    21. );
    22. uint32_t height = static_cast<uint32_t>(
    23. header[4] | (header[5] << 8) | (header[6] << 16) | (header[7] << 24)
    24. );
    25. // 4. 数据有效性检查
    26. if (width == 0 || height == 0 || width > 10000 || height > 10000) {
    27. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG,
    28. "Deserialize: invalid dimensions! width=%{public}u, height=%{public}u",
    29. width, height);
    30. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    31. }
    32. // 5. 计算图像数据大小
    33. size_t imageSize = width * height * sizeof(uint8_t);
    34. // 6. 分配ImageData结构体内存
    35. struct ImageData* img = new (std::nothrow) struct ImageData;
    36. if (img == nullptr) {
    37. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG,
    38. "Deserialize: ImageData allocation failed!");
    39. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    40. }
    41. // 7. 分配像素数据内存
    42. img->pixels = new (std::nothrow) uint8_t[imageSize];
    43. if (img->pixels == nullptr) {
    44. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG,
    45. "Deserialize: pixels allocation failed! size=%{public}zu", imageSize);
    46. delete img;
    47. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    48. }
    49. // 8. 设置图像属性
    50. img->width = width;
    51. img->height = height;
    52. // 9. 读取像素数据
    53. size_t pixelSize = imageSize;
    54. errorCode = read(img->pixels, &pixelSize, key);
    55. if (errorCode != FILE_CACHE_BOOST_SUCCESS || pixelSize != imageSize) {
    56. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG,
    57. "Deserialize: read pixels failed! errorCode=%{public}d, expected=%{public}zu, actual=%{public}zu",
    58. errorCode, imageSize, pixelSize);
    59. delete[] img->pixels;
    60. delete img;
    61. return FILE_CACHE_BOOST_CALLBACK_FAILURE;
    62. }
    63. // 10. 正确设置输出参数(修复原bug)
    64. *object = static_cast<void*>(img);
    65. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG,
    66. "Deserialize success! width=%{public}u, height=%{public}u, size=%{public}zu",
    67. width, height, imageSize);
    68. return FILE_CACHE_BOOST_CALLBACK_SUCCESS;
    69. }
  12. 调用HMS_FileCacheBoost_GetSerialObjectByKey获取缓存数据。

    收起
    自动换行
    深色代码主题
    复制
    1. napi_value OH_GetSerialObjectByKey(napi_env env, napi_callback_info info) {
    2. // 获取参数数量
    3. size_t argc = 1;
    4. napi_value args[1];
    5. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    6. // 检查参数数量
    7. if (argc < 1) {
    8. napi_throw_error(env, nullptr, "Invalid number of arguments");
    9. return nullptr;
    10. }
    11. char *key;
    12. size_t keyLen;
    13. napi_get_value_string_utf8(env, args[0], nullptr, 0, &keyLen);
    14. key = new char[keyLen + 1];
    15. napi_get_value_string_utf8(env, args[0], key, keyLen + 1, &keyLen);
    16. // 定义object
    17. void *object = nullptr;
    18. // 调用HMS_FileCacheBoost_GetSerialObjectByKey获取复杂类数据缓存
    19. int result = HMS_FileCacheBoost_GetSerialObjectByKey(
    20. reinterpret_cast<uint8_t*>(key), keyLen, Deserialize, &object
    21. );
    22. if (result == FILE_CACHE_BOOST_SUCCESS && object != nullptr) {
    23. // 获取成功,输出图像信息
    24. struct ImageData* img = static_cast<struct ImageData*>(object);
    25. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG,
    26. "GetSerialObject success! width=%{public}u, height=%{public}u",
    27. img->width, img->height);
    28. // 打印部分像素数据(前100字节)
    29. size_t printLen = std::min(img->width * img->height, static_cast<uint32_t>(100));
    30. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "First %{public}zu pixels:", printLen);
    31. for (size_t i = 0; i < printLen; i++) {
    32. OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG,
    33. "Pixel[%{public}zu]=%{public}c", i, img->pixels[i]);
    34. }
    35. // 释放ImageData对象内存
    36. delete[] img->pixels;
    37. delete img;
    38. } else {
    39. OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG,
    40. "GetSerialObject failed! result=%{public}d", result);
    41. }
    42. // 释放内存
    43. delete[] key;
    44. // 返回结果
    45. napi_value jsResult;
    46. napi_create_int32(env, result, &jsResult);
    47. return jsResult;
    48. }