用jni进行文件读写
1、Java代码写native方法如:publicnative String getFromC(String path);
2、生成头文件:在AndoridStudio的Termial选项下进入到java文件夹
执行javah native方法所在类的全类名如:javah com.xreal.arsearch.arsearch.NativeDetector
3、将生成的头文件复制到工程的jni目录下(jni目录和jniLibs与java目录同级)
4、在.cpp文件中引入生成的头文件如:
#include"com_xreal_arsearch_arsearch_NativeDetector.h"
5、将头文件中的头文件粘贴到.cpp文件中如:
JNIEXPORT jint JNICALLJava_com_xreal_arsearch_arsearch_NativeDetector_NativeFileClose
(JNIEnv*, jobject, jint);
删除上面的红字部分
6、(1)JNI读写文件.cpp代码
#include "com_xreal_arsearch_arsearch_NativeDetector.h"
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <stdlib.h>
#include <fcntl.h>
char* jstringTostring(JNIEnv*env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring =env->FindClass("java/lang/String");
jstring strencode =env->NewStringUTF("utf-8");
jmethodID mid =env->GetMethodID(clsstring, "getBytes","(Ljava/lang/String;)[B");
jbyteArray barr=(jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
jsize alen =env->GetArrayLength(barr);
jbyte* ba =env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen+ 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0);
return rtn;
}
int file_open(const char *filename,intflags)
{
int fd;
fd = open(filename, flags, 0666);
if (fd == -1)
return -1;
return fd;
}
int file_read(int fd, unsignedchar *buf, int size)
{
return read(fd, buf, size);
}
int file_close(int fd)
{
return close(fd);
}
jstring Java_com_xreal_arsearch_arsearch_NativeDetector_getFromC
(JNIEnv * env, jobject jobj, jstringjstr){
char*javaPath=jstringTostring(env,jstr);
unsigned char * buf;
int fd=file_open(javaPath,O_RDONLY);
int num=file_read(fd,buf,1024);
return (env)->NewStringUTF(javaPath);
};
jint Java_com_xreal_arsearch_arsearch_NativeDetector_NativeFileOpen
(JNIEnv *env, jobject jobj, jstringfilename, jint flags){
// const char *filename_char =(env)->GetStringUTFChars(env,filename, NULL);
char*javaPath=jstringTostring(env,filename);
return file_open(javaPath,flags);
}
jint Java_com_xreal_arsearch_arsearch_NativeDetector_NativeFileRead
(JNIEnv *env, jobject jobj, jint fd,jbyteArray buf, jint size){
unsigned char *buf_char= (unsigned char*)((env)->GetByteArrayElements(buf, NULL));
return file_read(fd,buf_char, size);
}
jint Java_com_xreal_arsearch_arsearch_NativeDetector_NativeFileClose
(JNIEnv *env, jobject jobj, jintfd){
return file_close(fd);
}
(2)java层代码
常用flags:
/*O_RDONLY以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以可读写方式打开文件。上述三种旗标是互斥的,也就是不可同时使用,但可与下列的旗标利用OR(|)运算符组合。
O_CREAT 若欲打开的文件不存在则自动建立该文件。
O_TRUNC 若文件存在并且以可写的方式打开时,此标志位会令文件长度重新清为0,也就是说文件内容清空。
O_APPEND 当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式加入到文件后面。
O_NONBLOCK 以不可阻断的方式打开文件,也就是无论有无数据读取或等待,都会立即返回进程之中。
O_SYNC 以同步的方式打开文件。
O_NOFOLLOW 如果参数pathname所指的文件为一符号连接,则会令打开文件失败。
O_DIRECTORY 如果参数pathname所指的文件并非为一目录,则会令打开文件失败。*/
byte[]buf_write=new byte[1024];
byte[] buf_read=new byte[1024];
int fd;
int O_RDWR = 02;
int O_CREAT = 0100; /* not fcntl */
String path = Constants.getFotonDirtory();
String fromC = NativeDetector.getInstance().getFromC(path +"test.txt");
//Toast.makeText(this,fromC,0).show();
fd = NativeDetector.getInstance().NativeFileOpen(fromC, O_CREAT | O_RDWR);
System.out.println("fd_read---->" + fd);
buf_read = new byte[buf_write.length];
int ret_read = NativeDetector.getInstance().NativeFileRead(fd, buf_read,buf_write.length);
System.out.println("读出返回结果" + ret_read);
try {
String gb2312 = new String(buf_read,"GB2312") + "";
Toast.makeText(this,gb2312,Toast.LENGTH_SHORT).show();
} catch (UnsupportedEncodingException e){
e.printStackTrace();
}
NativeDetector.getInstance().NativeFileClose(fd);
(3)NativeDetector类
package com.xreal.arsearch.arsearch; import org.opencv.core.Mat; /** * Created by Administrator on 2016/8/4 0004. */ public class NativeDetector { static { System.loadLibrary("JniTest"); //defaultConfig.ndk.moduleName } private static NativeDetector singleDetector = null; public static NativeDetector getInstance() { if (singleDetector == null) { singleDetector = new NativeDetector(); } return singleDetector; } public native boolean extractFeatures(long oImage, long descriptors); public native String getFromC(String path); public native int NativeFileOpen(String filename, int flags); public native int NativeFileRead(int fd, byte[] buf, int sizes); public native long NativeFileSeek(int fd, long Offset, int whence); public native int NativeFileClose(int fd); }(4)Application.mk
APP_STL := gnustl_static APP_CPPFLAGS := -frtti -fexceptions APP_ABI := armeabi armeabi-v7a(5)Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) OpenCV_INSTALL_MODULES := on OpenCV_CAMERA_MODULES := off OPENCV_LIB_TYPE :=SHARED ifeq ("$(wildcard $(OPENCV_MK_PATH))","") include ..\..\..\..\native\jni\OpenCV.mk else include $(OPENCV_MK_PATH) endif LOCAL_MODULE := JniTest LOCAL_SRC_FILES := \ E:\MrWangCode\arsearchdemochina\CarHelper-JNIDemo\arsearch\src\main\jni\JniTest.c \ E:\MrWangCode\arsearchdemochina\CarHelper-JNIDemo\arsearch\src\main\jni\NativeDetecor.cpp \ E:\MrWangCode\arsearchdemochina\CarHelper-JNIDemo\arsearch\src\main\jni\PatternDetector.cpp \ E:\MrWangCode\arsearchdemochina\CarHelper-JNIDemo\arsearch\src\main\jni\read.cpp \ LOCAL_LDLIBS += -lm -llog include $(BUILD_SHARED_LIBRARY)