tflite BuildFromFile()从资产文件夹读取的Android本机文件
我有Android原生代码(tflite BuildFromFile()从资产文件夹读取的Android本机文件,android,c++,tensorflow,android-ndk,tensorflow-lite,Android,C++,Tensorflow,Android Ndk,Tensorflow Lite,我有Android原生代码(C++shared object),在创建APK时希望读取assets文件夹中保存的模型文件 Tensorflow Lite有两个API:FromFile和FromBuffer static std::unique_ptr<FlatBufferModel> BuildFromFile(const char* filename, ErrorReporter* error_reporter); static std::unique_ptr<FlatBu
C++
shared object),在创建APK时希望读取assets
文件夹中保存的模型文件
Tensorflow Lite有两个API:FromFile和FromBuffer
static std::unique_ptr<FlatBufferModel> BuildFromFile(const char* filename, ErrorReporter* error_reporter);
static std::unique_ptr<FlatBufferModel> BuildFromBuffer(const char* buffer, size_t buffer_size, ErrorReporter* error_reporter);
C++
code:
private AssetManager mgr;
// Get mgr
mgr = getResources().getAssets();
AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
const char* filename = (const char*)NULL;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
char buf[BUFSIZ];
int nb_read = 0;
FILE* out = fopen(filename, "w");
while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
fwrite(buf, nb_read, 1, out);
fclose(out);
AAsset_close(asset);
}
AAssetDir_close(assetDir);
任何想法,如何访问assets
文件夹以使用BuildFromFile
?我不认为您可以使用BuildFromFile
,而不将资产文件复制到本地文件(这与您上面所做的操作相当,在这种情况下,buildfromfuffer
更方便)
如果要避免内存复制,请执行以下操作:
(Java)通过内存映射加载模型
(java)通过JNI将映射文件传递给C++,如定义以下方法:
(C++)使用缓冲区文件初始化模型:
Java_uxxxxxx_initJniWithByteBuffer(JNIEnv*env,jclass thiz,jobject model_buffer){\
char*buffer=static_cast(env->GetDirectBufferAddress(model_buffer))\
size\u t buffer\u size=static\u cast(env->GetDirectBufferCapacity(model\u buffer))\
}
AssetFileDescriptor fileDescriptor = getResources().getAssets().openFd(filePath);\
FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());\
FileChannel fileChannel = inputStream.getChannel();\
long startOffset = fileDescriptor.getStartOffset();\
long declaredLength = fileDescriptor.getDeclaredLength();\
MappedByteBuffer modelBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
private static native void initJniWithByteBuffer(ByteBuffer modelBuffer)
Java_xxxxxx_initJniWithByteBuffer(JNIEnv* env, jclass thiz, jobject model_buffer) {\
char* buffer = static_cast<char*>(env->GetDirectBufferAddress(model_buffer));\
size_t buffer_size = static_cast<size_t>(env->GetDirectBufferCapacity(model_buffer));\
}