最近研究native android相关内容,其中最棘手的就是文件读写问题,最主要的是相关的文档很少。这里写下我所知道的方法。
由于本人使用的是Android14[arm64-v8a]版本的设备,能访问的路径相当有限,如果想要访问更多的路径,就不得不申请权限了。可用的路径如下:
1. assets:/assets
2. internalDataPath: /data/user/0/com.example.org/files
3. externalDataPath:/storage/emulated/0/Android/data/com.example.org/files
4. obbPath:/storage/emulated/0/Android/obb/com.example.org
5. Document:/storage/emulated/0/Document
6. Download:/storage/emulated/0/Download
一、Apk中的assets目录
以下列android工程为例,将资源文件放置在assets目录下,android studio打包时会将文件打包到apk中。
std::vector<char> ReadFromAssets(const char *path,android_app* app) {if(app==nullptr) return {};AAsset* file = AAssetManager_open(app->activity->assetManager,path,AASSET_MODE_BUFFER);if(file==nullptr) return {};size_t len = AAsset_getLength(file);std::vector<char> data;data.resize(len);AAsset_read(file, data.data(), len);AAsset_close(file);return data;
}example:
dir:assets/image/x.png
data = ReadFromAssets("image/x.png",app);
二、其他目录
2~6路径作为根目录,在对应路径下创建或访问子文件或路径是可以的,用下列方法访问完整路径即可。遗憾的是,仅当app执行一次mkdir(filePath.c_str(), 0774)后,app才能正常读取创建的目录下的文件。当清楚app全部数据后,将会失去目录的读写权限,只有删除目录并让app重新创建才能使用。
#include <filesystem>
#include <sys/stat.h>
std::vector<char> ReadFileFromPath(const char* path) {std::filesystem::path absolutePath(path);auto filePath = absolutePath.parent_path();struct stat sb{};int32_t res = stat(filePath.c_str(), &sb);if (0 == res && sb.st_mode & S_IFDIR){//has dir}else if (ENOENT == errno){//not has dir,create dirres = mkdir(filePath.c_str(), 0774);}if(0!=res) return {};std::ifstream file;file.open(path, std::ifstream::in);if(!file.is_open()){return {};}file.seekg(0,std::ifstream ::end);auto len = file.tellg();std::vector<char> data;if(len>0){file.seekg(0,std::ifstream ::beg);data.resize(len);file.read(data.data(),static_cast<int>(len));}file.close();return data;
}example:
ReadFileFromPath("/storage/emulated/0/Android/data/com.example.org/files/data/123.obb");