You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android CMake+JNI场景下使用boost::property_tree读取json文件找不到如何解决

Android CMake+JNI项目中boost read_json读取本地文件解决方案

你遇到的报错核心原因有两个:

  1. Android应用的项目源码文件不会直接打包到设备的可访问文件系统中,你在项目里创建的conf/file.json默认不会被打包进APK,更不会出现在设备的文件系统里
  2. 你代码中使用的相对路径conf/file.json是相对于App进程的当前工作目录,Android App进程默认工作目录为/,无读取权限也不存在对应文件

步骤1:放置配置文件到assets目录

在Android项目的app/src/main/路径下创建assets目录,再在assets目录下新建conf子目录,将你的file.json放入assets/conf/路径下。
默认Android Gradle插件会自动把assets目录下的所有资源打包进APK,不需要额外配置。

步骤2:启动时拷贝assets资源到App私有存储目录

APK中的assets资源属于安装包内的压缩资源,无法直接通过文件路径访问,需要在App启动时(比如MainActivity的onCreate阶段)将assets下的conf目录整体拷贝到App的内部私有存储路径,示例Java拷贝代码如下:

private void copyAssetsToFilesDir() {
    AssetManager assetManager = getAssets();
    String[] files;
    try {
        files = assetManager.list("conf");
        File outDir = new File(getFilesDir(), "conf");
        if (!outDir.exists()) outDir.mkdirs();
        for (String filename : files) {
            InputStream in = assetManager.open("conf/" + filename);
            File outFile = new File(outDir, filename);
            FileOutputStream out = new FileOutputStream(outFile);
            byte[] buffer = new byte[1024];
            int read;
            while ((read = in.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }
            in.close();
            out.flush();
            out.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

拷贝完成后,file.json在设备上的绝对路径为/data/data/[你的应用包名]/files/conf/file.json,该路径不需要申请任何存储权限即可读写。

步骤3:适配C++读取逻辑(二选一即可)

方案A:不修改原有C++代码(推荐)

在JNI层调用chdir函数切换进程工作目录到App私有存储的根路径即可:

  1. Java层把私有目录路径传给JNI:
// 在MainActivity中调用
nativeSetWorkDir(getFilesDir().getAbsolutePath());
  1. JNI层实现切换工作目录:
#include <unistd.h>

extern "C"
JNIEXPORT void JNICALL
Java_你的包名_MainActivity_nativeSetWorkDir(JNIEnv *env, jobject thiz, jstring work_dir) {
    const char *dir = env->GetStringUTFChars(work_dir, nullptr);
    chdir(dir);
    env->ReleaseStringUTFChars(work_dir, dir);
}

切换完成后你原来的boost::property_tree::json_parser::read_json("conf/file.json", config);代码不需要任何修改即可正常运行。

方案B:拼接绝对路径读取

你也可以把私有目录路径传入JNI后拼接成完整的绝对路径传给read_json接口:

// 假设已经获取到java层传入的filesDir路径
std::string json_path = std::string(files_dir) + "/conf/file.json";
boost::property_tree::json_parser::read_json(json_path, config);

内容的提问来源于stack exchange,提问作者user16967562

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 06:15:03