博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android NDK JNI C++ <11>JNI_OnLoad具体实现
阅读量:6352 次
发布时间:2019-06-22

本文共 20827 字,大约阅读时间需要 69 分钟。

这一篇给出<9> ,<10>前面内容的demo作为进一步了解<9>,<10>的用法.<Android JNI层实现文件的read、write与seek操作>

1、

          在Android的java层实现文件的读写操作是非常简单的.

          在JNI层实现文件的读写操作的话,就要使用到linux的读写函数了。

 

2、打开文件

 

[cpp]
  1. int open( const char *pathname,int flags, int mode);  
int open( const char *pathname,int flags, int mode);

 

返回值:为一个文件句柄(fd),供read、write等操作。

参数:

pathname: 打开的文件所在路径字符串。如

 

[java]
  1. String filename = "/sdcard/test.txt";  
String filename = "/sdcard/test.txt";

 

flags: 文件打开的方式

flag之间可以作“与”运算,如

 

[java]
  1. open(filename, O_CREAT  | O_RDWR,mode);  
open(filename, O_CREAT  | O_RDWR,mode);

 

常用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所指的文件并非为一目录,则会令打开文件失败。

 

 

mode: 文件存储权限

S_IRWXU00700 权限,代表该文件所有者具有可读、可写及可执行的权限。 S_IRUSR 或S_IREAD,00400权限,代表该文件所有者具有可读取的权限。 S_IWUSR 或S_IWRITE,00200 权限,代表该文件所有者具有可写入的权限。 S_IXUSR 或S_IEXEC,00100 权限,代表该文件所有者具有可执行的权限。 S_IRWXG 00070权限,代表该文件用户组具有可读、可写及可执行的权限。 S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。 S_IWGRP 00020权限,代表该文件用户组具有可写入的权限。 S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限。 S_IRWXO 00007权限,代表其他用户具有可读、可写及可执行的权限。 S_IROTH 00004 权限,代表其他用户具有可读的权限 S_IWOTH 00002权限,代表其他用户具有可写入的权限。 S_IXOTH 00001 权限,代表其他用户具有可执行的权限。
3、文件的读(read)操作

[cpp]
  1. int read(int fd, unsigned char *buf, int size);   
int read(int fd, unsigned char *buf, int size);

 

返回值:返回实际读取到的字节数,如果返回0,表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动。

参数

fd:表示文件句柄,是由open函数得到

buf:read()函数会把fd 所指的文件传送count个字节到buf指针所指的内存中

size:要读取的字节数

 

4、写入操作

[cpp]
  1. int write (int fd, const unsigned char *buf, int size);   
int write (int fd, const unsigned char *buf, int size);

返回值 :如果成功write(),就会返回实际写入的字节数。当有错误发生时则返回-1

 

参数

fd:同上

buf:将要写入到文件里面的内容。

size:要写入的字节数

 

5、跳转操作

 

[cpp]
  1. int64_t seek(int fd, int64_t pos, int whence)  
int64_t seek(int fd, int64_t pos, int whence)

返回值:成功时则返回目前的读写位置,也就是距离文件开头多少个字节,若有错误则返回-1。

 

参数

fd:同上

pos:跳转的相对量,可正可负,表示相对位置的前后关系

whence:跳转的方向,whence取值如下所示

 

[cpp]
  1. int SEEK_SET   =        0;//将读写位置指向文件头后再增加offset个位移量。  
  2. int SEEK_CUR   =        1;//以目前的读写位置往后增加offset个位移量。  
  3. int EEK_END    =        2;//将读写位置指向文件尾后再增加offset个位移量。  
int SEEK_SET   =		0;//将读写位置指向文件头后再增加offset个位移量。	int SEEK_CUR   =		1;//以目前的读写位置往后增加offset个位移量。	int EEK_END    =		2;//将读写位置指向文件尾后再增加offset个位移量。

注:当size参数=0;whence = SEEK_END;时返回值即为文件大小。

 

 

6、关闭操作

 

[cpp]
  1. int close(int fd)  
int close(int fd)

 

 

7、简单示例

效果图:

 

 

7.1、JNI代码:(有JNI_onLoad函数)

 

[cpp]
  1. //fs.c  
  2. #include <unistd.h>  
  3. #include <sys/stat.h>  
  4. #include <sys/time.h>  
  5. #include <stdlib.h>  
  6. #include <fcntl.h>  
  7.   
  8.   
  9.  int file_open(const char *filename, int flags)  
  10. {  
  11.     int fd;  
  12.     
  13.     fd = open(filename, flags, 0666);  
  14.     if (fd == -1)  
  15.         return -1;  
  16.   
  17.     return fd;  
  18. }  
  19.   
  20.  int file_read(int fd, unsigned char *buf, int size)  
  21. {  
  22.       
  23.     return read(fd, buf, size);  
  24. }  
  25.   
  26.  int file_write(int fd, const unsigned char *buf, int size)  
  27. {  
  28.       
  29.     return write(fd, buf, size);  
  30. }  
  31.   
  32.   
  33.  int64_t file_seek(int fd, int64_t pos, int whence)  
  34. {  
  35.       
  36.     if (whence == 0x10000) {  
  37.         struct stat st;  
  38.         int ret = fstat(fd, &st);  
  39.         return ret < 0 ? -1 : st.st_size;  
  40.     }  
  41.     return lseek(fd, pos, whence);  
  42. }  
  43.   
  44.  int file_close(int fd)  
  45. {  
  46.      
  47.     return close(fd);  
  48. }  
//fs.c#include 
#include
#include
#include
#include
int file_open(const char *filename, int flags){ int fd; fd = open(filename, flags, 0666); if (fd == -1) return -1; return fd;} int file_read(int fd, unsigned char *buf, int size){ return read(fd, buf, size);} int file_write(int fd, const unsigned char *buf, int size){ return write(fd, buf, size);} int64_t file_seek(int fd, int64_t pos, int whence){ if (whence == 0x10000) { struct stat st; int ret = fstat(fd, &st); return ret < 0 ? -1 : st.st_size; } return lseek(fd, pos, whence);} int file_close(int fd){ return close(fd);}
[cpp]
  1. //jni.c  
  2. #define TAG "fs_jni"  
  3.   
  4. #include <android/log.h>  
  5. #include "jniUtils.h"  
  6.   
  7.   
  8.   
  9. static const charconst kClassPathName = "com/conowen/fs/FsActivity";  
  10.   
  11.   
  12. jint  
  13. Java_com_conowen_fs_FsActivity_NativeFileOpen( JNIEnv* env, jobject thiz,jstring filename,jint flags ){     
  14.   
  15.       
  16.      const char *filename_char = (*env)->GetStringUTFChars(env,filename, NULL);  
  17.    
  18.     return file_open(filename_char, flags);  
  19. }  
  20. jint  
  21. Java_com_conowen_fs_FsActivity_NativeFileRead(JNIEnv* env, jobject thiz,int fd,jbyteArray buf,jint size){  
  22.   
  23.     unsigned char *buf_char = (char*)((*env)->GetByteArrayElements(env,buf, NULL));  
  24.   
  25.     return file_read(fd, buf_char,  size);  
  26. }  
  27.   
  28. jint  
  29. Java_com_conowen_fs_FsActivity_NativeFileWrite(JNIEnv* env, jobject thiz,int fd,jbyteArray buf,jint size){  
  30.       
  31.     unsigned char *buf_char = (char*)((*env)->GetByteArrayElements(env,buf, NULL));  
  32.   
  33.     return file_write(fd, buf_char,  size);  
  34. }  
  35.   
  36. jlong  
  37. Java_com_conowen_fs_FsActivity_NativeFileSeek(JNIEnv* env, jobject thiz,int fd,jlong Offset,jint whence){  
  38.   
  39.     return file_seek(fd, Offset,  whence);  
  40. }  
  41.   
  42. jint  
  43. Java_com_conowen_fs_FsActivity_NativeFileClose(JNIEnv* env, jobject thiz,int fd){  
  44.   
  45.     return file_close(fd);  
  46. }  
  47.   
  48. /******************************JNI registration.************************************/  
  49. static JNINativeMethod gMethods[] = {  
  50.     {
    "NativeFileOpen",       "(Ljava/lang/String;I)I",           (void *)Java_com_conowen_fs_FsActivity_NativeFileOpen},  
  51.     {
    "NativeFileRead",       "(I[BI)I",                          (void *)Java_com_conowen_fs_FsActivity_NativeFileRead},  
  52.     {
    "NativeFileWrite",      "(I[BI)I",                          (void *)Java_com_conowen_fs_FsActivity_NativeFileWrite},  
  53.     {
    "NativeFileSeek",       "(IJI)J",                           (void *)Java_com_conowen_fs_FsActivity_NativeFileSeek},  
  54.     {
    "NativeFileClose",      "(I)I",                             (void *)Java_com_conowen_fs_FsActivity_NativeFileClose},  
  55. };  
  56.   
  57. int register_com_conowen_fs_FsActivity(JNIEnv *env) {  
  58.     return jniRegisterNativeMethods(env, kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));  
  59.       
  60. }  
//jni.c#define TAG "fs_jni"#include 
#include "jniUtils.h"static const char* const kClassPathName = "com/conowen/fs/FsActivity";jintJava_com_conowen_fs_FsActivity_NativeFileOpen( JNIEnv* env, jobject thiz,jstring filename,jint flags ){ const char *filename_char = (*env)->GetStringUTFChars(env,filename, NULL); return file_open(filename_char, flags);}jintJava_com_conowen_fs_FsActivity_NativeFileRead(JNIEnv* env, jobject thiz,int fd,jbyteArray buf,jint size){ unsigned char *buf_char = (char*)((*env)->GetByteArrayElements(env,buf, NULL)); return file_read(fd, buf_char, size);}jintJava_com_conowen_fs_FsActivity_NativeFileWrite(JNIEnv* env, jobject thiz,int fd,jbyteArray buf,jint size){ unsigned char *buf_char = (char*)((*env)->GetByteArrayElements(env,buf, NULL)); return file_write(fd, buf_char, size);}jlongJava_com_conowen_fs_FsActivity_NativeFileSeek(JNIEnv* env, jobject thiz,int fd,jlong Offset,jint whence){ return file_seek(fd, Offset, whence);}jintJava_com_conowen_fs_FsActivity_NativeFileClose(JNIEnv* env, jobject thiz,int fd){ return file_close(fd);}/******************************JNI registration.************************************/static JNINativeMethod gMethods[] = { {"NativeFileOpen", "(Ljava/lang/String;I)I", (void *)Java_com_conowen_fs_FsActivity_NativeFileOpen}, {"NativeFileRead", "(I[BI)I", (void *)Java_com_conowen_fs_FsActivity_NativeFileRead}, {"NativeFileWrite", "(I[BI)I", (void *)Java_com_conowen_fs_FsActivity_NativeFileWrite}, {"NativeFileSeek", "(IJI)J", (void *)Java_com_conowen_fs_FsActivity_NativeFileSeek}, {"NativeFileClose", "(I)I", (void *)Java_com_conowen_fs_FsActivity_NativeFileClose},};int register_com_conowen_fs_FsActivity(JNIEnv *env) { return jniRegisterNativeMethods(env, kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0])); }
[cpp]
  1. //jniUtils.h  
  2. #ifndef _JNI_UTILS_H_  
  3. #define _JNI_UTILS_H_  
  4.   
  5. #include <stdlib.h>  
  6. #include <jni.h>  
  7.   
  8. #ifdef __cplusplus  
  9. extern "C"  
  10. {  
  11. #endif  
  12.   
  13. int jniThrowException(JNIEnv* env, const char* className, const char* msg);  
  14.   
  15. JNIEnv* getJNIEnv();  
  16.   
  17. int jniRegisterNativeMethods(JNIEnv* env,  
  18.                              const char* className,  
  19.                              const JNINativeMethod* gMethods,  
  20.                              int numMethods);  
  21.   
  22. #ifdef __cplusplus  
  23. }  
  24. #endif  
  25.   
  26. #endif /* _JNI_UTILS_H_ */  
//jniUtils.h#ifndef _JNI_UTILS_H_#define _JNI_UTILS_H_#include 
#include
#ifdef __cplusplusextern "C"{#endifint jniThrowException(JNIEnv* env, const char* className, const char* msg);JNIEnv* getJNIEnv();int jniRegisterNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods);#ifdef __cplusplus}#endif#endif /* _JNI_UTILS_H_ */
[cpp]
  1. //onLoad.cpp  
  2. #define TAG "fs_onLoad"  
  3.   
  4. #include <android/log.h>  
  5. #include "jniUtils.h"  
  6.   
  7. extern "C" {  
  8.   
  9. extern int register_com_conowen_fs_FsActivity(JNIEnv *env);  
  10.   
  11. }  
  12.   
  13. static JavaVM *sVm;  
  14.   
  15. /* 
  16.  * Throw an exception with the specified class and an optional message. 
  17.  */  
  18. int jniThrowException(JNIEnv* env, const char* className, const char* msg) {  
  19.     jclass exceptionClass = env->FindClass(className);  
  20.     if (exceptionClass == NULL) {  
  21.         __android_log_print(ANDROID_LOG_ERROR,  
  22.                 TAG,  
  23.                 "Unable to find exception class %s",  
  24.                         className);  
  25.         return -1;  
  26.     }  
  27.   
  28.     if (env->ThrowNew(exceptionClass, msg) != JNI_OK) {  
  29.         __android_log_print(ANDROID_LOG_ERROR,  
  30.                 TAG,  
  31.                 "Failed throwing '%s' '%s'",  
  32.                 className, msg);  
  33.     }  
  34.     return 0;  
  35. }  
  36.   
  37. JNIEnv* getJNIEnv() {  
  38.     JNIEnv* env = NULL;  
  39.     if (sVm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {  
  40.         __android_log_print(ANDROID_LOG_ERROR,  
  41.                             TAG,  
  42.                             "Failed to obtain JNIEnv");  
  43.         return NULL;  
  44.     }  
  45.     return env;  
  46. }  
  47.   
  48. /* 
  49.  * Register native JNI-callable methods. 
  50.  * 
  51.  * "className" looks like "java/lang/String". 
  52.  */  
  53. int jniRegisterNativeMethods(JNIEnv* env,  
  54.                              const char* className,  
  55.                              const JNINativeMethod* gMethods,  
  56.                              int numMethods)  
  57. {  
  58.     jclass clazz;  
  59.   
  60.     __android_log_print(ANDROID_LOG_INFO, TAG, "Registering %s natives\n", className);  
  61.     clazz = env->FindClass(className);  
  62.     if (clazz == NULL) {  
  63.         __android_log_print(ANDROID_LOG_ERROR, TAG, "Native registration unable to find class '%s'\n", className);  
  64.         return -1;  
  65.     }  
  66.     if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {  
  67.         __android_log_print(ANDROID_LOG_ERROR, TAG, "RegisterNatives failed for '%s'\n", className);  
  68.         return -1;  
  69.     }  
  70.     return 0;  
  71. }  
  72. //Dalvik虚拟机加载C库时,第一件事是调用JNI_OnLoad()函数  
  73. jint JNI_OnLoad(JavaVM* vm, void* reserved) {  
  74.     JNIEnv* env = NULL;  
  75.     jint result = JNI_ERR;  
  76.     sVm = vm;  
  77.   
  78.     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {  
  79.         __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv failed!");  
  80.         return result;  
  81.     }  
  82.   
  83.     __android_log_print(ANDROID_LOG_INFO, TAG, "loading . . .");  
  84.   
  85.   
  86.     if(register_com_conowen_fs_FsActivity(env) != JNI_OK) {  
  87.         __android_log_print(ANDROID_LOG_ERROR, TAG, "can't load register_com_conowen_fs_FsActivity");  
  88.         goto end;  
  89.     }  
  90.   
  91.     __android_log_print(ANDROID_LOG_INFO, TAG, "loaded");  
  92.   
  93.     result = JNI_VERSION_1_4;  
  94.   
  95. end:  
  96.     return result;  
  97. }  
//onLoad.cpp#define TAG "fs_onLoad"#include 
#include "jniUtils.h"extern "C" {extern int register_com_conowen_fs_FsActivity(JNIEnv *env);}static JavaVM *sVm;/* * Throw an exception with the specified class and an optional message. */int jniThrowException(JNIEnv* env, const char* className, const char* msg) { jclass exceptionClass = env->FindClass(className); if (exceptionClass == NULL) { __android_log_print(ANDROID_LOG_ERROR, TAG, "Unable to find exception class %s", className); return -1; } if (env->ThrowNew(exceptionClass, msg) != JNI_OK) { __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed throwing '%s' '%s'", className, msg); } return 0;}JNIEnv* getJNIEnv() { JNIEnv* env = NULL; if (sVm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to obtain JNIEnv"); return NULL; } return env;}/* * Register native JNI-callable methods. * * "className" looks like "java/lang/String". */int jniRegisterNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods){ jclass clazz; __android_log_print(ANDROID_LOG_INFO, TAG, "Registering %s natives\n", className); clazz = env->FindClass(className); if (clazz == NULL) { __android_log_print(ANDROID_LOG_ERROR, TAG, "Native registration unable to find class '%s'\n", className); return -1; } if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { __android_log_print(ANDROID_LOG_ERROR, TAG, "RegisterNatives failed for '%s'\n", className); return -1; } return 0;}//Dalvik虚拟机加载C库时,第一件事是调用JNI_OnLoad()函数jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = JNI_ERR; sVm = vm; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv failed!"); return result; } __android_log_print(ANDROID_LOG_INFO, TAG, "loading . . ."); if(register_com_conowen_fs_FsActivity(env) != JNI_OK) { __android_log_print(ANDROID_LOG_ERROR, TAG, "can't load register_com_conowen_fs_FsActivity"); goto end; } __android_log_print(ANDROID_LOG_INFO, TAG, "loaded"); result = JNI_VERSION_1_4;end: return result;}

 

7.2、Android.mk文件

 

[cpp]
  1. LOCAL_PATH := $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_MODULE    := fs  
  6. LOCAL_SRC_FILES := fs.c jni.c onLoad.cpp  
  7. LOCAL_LDLIBS  += -llog  
  8.   
  9. include $(BUILD_SHARED_LIBRARY)  
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := fsLOCAL_SRC_FILES := fs.c jni.c onLoad.cppLOCAL_LDLIBS  += -lloginclude $(BUILD_SHARED_LIBRARY)

 

 

7.3、java层代码

 

[java]
  1. /* author:conowen 
  2.  * data:2012.5.1 
  3.  * e-mail:conowen@hotmail.com 
  4.  */  
  5. package com.conowen.fs;  
  6.   
  7. import java.io.UnsupportedEncodingException;  
  8.   
  9. import android.app.Activity;  
  10. import android.os.Bundle;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.widget.Button;  
  14. import android.widget.EditText;  
  15. import android.widget.TextView;  
  16.   
  17. public class FsActivity extends Activity {  
  18.     String filename = "/sdcard/test.txt";  
  19.     EditText writestrET;  
  20.     Button writeBT;  
  21.     Button readBT;  
  22.     Button seekBT;  
  23.     TextView readTV;  
  24.     String writeStr;  
  25.     byte[] buf_write;  
  26.     byte[] buf_read;  
  27.     int fd;  
  28.       
  29.     int O_ACCMODE  =    0003;  
  30.     int O_RDONLY   =      00;  
  31.     int O_WRONLY   =      01;  
  32.     int O_RDWR     =      02;  
  33.     int O_CREAT    =    0100/* not fcntl */  
  34.     int O_EXCL     =    0200/* not fcntl */  
  35.     int O_NOCTTY   =   0400/* not fcntl */  
  36.     int O_TRUNC    =   01000/* not fcntl */  
  37.     int O_APPEND   =   02000;  
  38.     int O_NONBLOCK =   04000;  
  39.     int O_NDELAY   = O_NONBLOCK;  
  40.     int O_SYNC     =  010000;  
  41.     int O_FSYNC    =  O_SYNC;  
  42.     int O_ASYNC    =  020000;  
  43.       
  44.     int SEEK_SET   =        0;//将读写位置指向文件头后再增加offset个位移量。  
  45.     int SEEK_CUR   =        1;//以目前的读写位置往后增加offset个位移量。  
  46.     int EEK_END    =        2;//将读写位置指向文件尾后再增加offset个位移量。   
  47.       
  48.     /** Called when the activity is first created. */  
  49.     @Override  
  50.     public void onCreate(Bundle savedInstanceState) {  
  51.         super.onCreate(savedInstanceState);  
  52.         setContentView(R.layout.main);  
  53.         writestrET = (EditText) findViewById(R.id.writeET);  
  54.         writeBT = (Button) findViewById(R.id.writeBT);  
  55.         readBT = (Button) findViewById(R.id.readBT);  
  56.         seekBT = (Button) findViewById(R.id.seekBT);  
  57.         readTV = (TextView) findViewById(R.id.readTV);  
  58.         writeBT.setOnClickListener(new OnClickListener() {  
  59.   
  60.             @Override  
  61.             public void onClick(View v) {  
  62.                 // TODO Auto-generated method stub  
  63.                 fd = NativeFileOpen(filename, O_CREAT  | O_RDWR);  
  64.                 System.out.println("fd_write---->" + fd);  
  65.                 writeStr = writestrET.getText().toString();  
  66.                 buf_write = writeStr.getBytes();  
  67.                 int ret_write = NativeFileWrite(fd, buf_write, buf_write.length);  
  68.                 System.out.println("写入返回结果" + ret_write);  
  69.                 NativeFileClose(fd);  
  70.   
  71.             }  
  72.         });  
  73.         readBT.setOnClickListener(new OnClickListener() {  
  74.   
  75.             @Override  
  76.             public void onClick(View v) {  
  77.                 // TODO Auto-generated method stub  
  78.                 fd = NativeFileOpen(filename, O_CREAT  | O_RDWR);  
  79.                 System.out.println("fd_read---->" + fd);  
  80.                 buf_read = new byte[buf_write.length];  
  81.                 int ret_read = NativeFileRead(fd, buf_read, buf_write.length);  
  82.                   
  83.                 System.out.println("读出返回结果" + ret_read);  
  84.                 try {  
  85.                     readTV.setText( new String(buf_read, "GB2312") + "");  
  86.                 } catch (UnsupportedEncodingException e) {  
  87.                     // TODO Auto-generated catch block  
  88.                     e.printStackTrace();  
  89.                 }  
  90.                 NativeFileClose(fd);  
  91.             }  
  92.         });  
  93.         seekBT.setOnClickListener(new OnClickListener() {  
  94.   
  95.             @Override  
  96.             public void onClick(View v) {  
  97.                 // TODO Auto-generated method stub  
  98.                 fd = NativeFileOpen(filename, O_CREAT  | O_RDWR);  
  99.                 long Offset=20;  
  100.                 long ret_seek =NativeFileSeek(fd, Offset, SEEK_CUR);  
  101.               
  102.                 System.out.println("seek返回结果" + ret_seek);  
  103.                   
  104.                 NativeFileClose(fd);  
  105.                 /*    1) 欲将读写位置移到文件开头时: 
  106.                          lseek(int fildes,0,SEEK_SET); 
  107.                      2) 欲将读写位置移到文件尾时: 
  108.                          lseek(int fildes,0,SEEK_END); 
  109.                      3) 想要取得目前文件位置时: 
  110.                          lseek(int fildes,0,SEEK_CUR); 
  111.                 返回值:当调用成功时则返回目前的读写位置,也就是距离文件开头多少个字节。若有错误则返回-1,errno 会存放错误代码。 
  112.                  * */  
  113.             }  
  114.         });  
  115.   
  116.     }  
  117.   
  118.     public native int NativeFileOpen(String filename, int flags);  
  119.   
  120.     public native int NativeFileRead(int fd, byte[] buf, int sizes);  
  121.   
  122.     public native int NativeFileWrite(int fd, byte[] buf, int sizes);  
  123.   
  124.     public native long NativeFileSeek(int fd, long Offset, int whence);  
  125.     //Offset:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)。  
  126.   
  127.     public native int NativeFileClose(int fd);  
  128.   
  129.     static {  
  130.         System.loadLibrary("fs");  
  131.     }  
  132. }  
/* author:conowen * data:2012.5.1 * e-mail:conowen@hotmail.com */package com.conowen.fs;import java.io.UnsupportedEncodingException;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;public class FsActivity extends Activity {	String filename = "/sdcard/test.txt";	EditText writestrET;	Button writeBT;	Button readBT;	Button seekBT;	TextView readTV;	String writeStr;	byte[] buf_write;	byte[] buf_read;	int fd;		int O_ACCMODE  =    0003;	int O_RDONLY   =      00;	int O_WRONLY   =      01;	int O_RDWR     =      02;	int O_CREAT    =    0100; /* not fcntl */	int O_EXCL     =    0200; /* not fcntl */	int O_NOCTTY   =   0400; /* not fcntl */	int O_TRUNC    =   01000; /* not fcntl */	int O_APPEND   =   02000;	int O_NONBLOCK =   04000;	int O_NDELAY   = O_NONBLOCK;	int O_SYNC     =  010000;	int O_FSYNC    =  O_SYNC;	int O_ASYNC    =  020000;		int SEEK_SET   =		0;//将读写位置指向文件头后再增加offset个位移量。	int SEEK_CUR   =		1;//以目前的读写位置往后增加offset个位移量。	int EEK_END    =		2;//将读写位置指向文件尾后再增加offset个位移量。 		/** Called when the activity is first created. */	@Override	public void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.main);		writestrET = (EditText) findViewById(R.id.writeET);		writeBT = (Button) findViewById(R.id.writeBT);		readBT = (Button) findViewById(R.id.readBT);		seekBT = (Button) findViewById(R.id.seekBT);		readTV = (TextView) findViewById(R.id.readTV);		writeBT.setOnClickListener(new OnClickListener() {			@Override			public void onClick(View v) {				// TODO Auto-generated method stub				fd = NativeFileOpen(filename, O_CREAT  | O_RDWR);				System.out.println("fd_write---->" + fd);				writeStr = writestrET.getText().toString();				buf_write = writeStr.getBytes();				int ret_write = NativeFileWrite(fd, buf_write, buf_write.length);				System.out.println("写入返回结果" + ret_write);				NativeFileClose(fd);			}		});		readBT.setOnClickListener(new OnClickListener() {			@Override			public void onClick(View v) {				// TODO Auto-generated method stub				fd = NativeFileOpen(filename, O_CREAT  | O_RDWR);				System.out.println("fd_read---->" + fd);				buf_read = new byte[buf_write.length];				int ret_read = NativeFileRead(fd, buf_read, buf_write.length);								System.out.println("读出返回结果" + ret_read);				try {					readTV.setText( new String(buf_read, "GB2312") + "");				} catch (UnsupportedEncodingException e) {					// TODO Auto-generated catch block					e.printStackTrace();				}				NativeFileClose(fd);			}		});		seekBT.setOnClickListener(new OnClickListener() {			@Override			public void onClick(View v) {				// TODO Auto-generated method stub				fd = NativeFileOpen(filename, O_CREAT  | O_RDWR);				long Offset=20;				long ret_seek =NativeFileSeek(fd, Offset, SEEK_CUR);							System.out.println("seek返回结果" + ret_seek);								NativeFileClose(fd);				/*    1) 欲将读写位置移到文件开头时: 						 lseek(int fildes,0,SEEK_SET); 					 2) 欲将读写位置移到文件尾时: 						 lseek(int fildes,0,SEEK_END); 					 3) 想要取得目前文件位置时: 						 lseek(int fildes,0,SEEK_CUR);				返回值:当调用成功时则返回目前的读写位置,也就是距离文件开头多少个字节。若有错误则返回-1,errno 会存放错误代码。				 * */			}		});	}	public native int NativeFileOpen(String filename, int flags);	public native int NativeFileRead(int fd, byte[] buf, int sizes);	public native int NativeFileWrite(int fd, byte[] buf, int sizes);	public native long NativeFileSeek(int fd, long Offset, int whence);	//Offset:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)。	public native int NativeFileClose(int fd);	static {		System.loadLibrary("fs");	}}

 

最后记得在manifest.xml里面加上SD卡操作权限

 

[html]
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
  2. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>  
demo来自 : # 这一篇和我的第8篇的读写文件的区别,另外,一定记得加权限,我前面就是忘了,所以总以为的程序的问题,要调试jni还是挺麻烦的.

转载地址:http://malla.baihongyu.com/

你可能感兴趣的文章
datatable 获取最大值
查看>>
sqlserver2012一直显示正在还原(Restoring)和从单用户转换成多用户模式(单用户连接中)...
查看>>
spark复习总结02
查看>>
李瑞红201771010111《第九周学习总结》
查看>>
[译]ZOOKEEPER RECIPES-Barriers
查看>>
NFC 鏈表操作
查看>>
pymongo模块
查看>>
第0次作业
查看>>
Ubuntu里设置python默认版本为python3(转载)
查看>>
快排+折半查找
查看>>
c# GC 新典型
查看>>
ssh bash 通配符
查看>>
seajs在jquery多个版本下引用jquery的插件的方案
查看>>
关于网络上java,php和.net的“口角之争“的一点想法 !
查看>>
python 第二周(第十三天) 我的python成长记 一个月搞定python数据挖掘!(21) -正则表达式re...
查看>>
[POI2011]SEJ-Strongbox
查看>>
20文件
查看>>
Android开发Intent应用概述
查看>>
【Go】并发编程
查看>>
VMware虚拟化NSX-Manager命令行更改admin用户密码
查看>>