Android的NDK开发(5)————Android JNI层实现文件的read、write与seek操作

1、

          在Android的java层实现文件的读写操作是非常简单的,可以参看之前写的博文:http://blog.csdn.net/conowen/article/details/7296121

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


2、打开文件

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

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


参数:

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

  1. String filename = "/sdcard/test.txt"
String filename = "/sdcard/test.txt";

flags: 文件打开的方式

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

  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)操作

  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、写入操作

  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、跳转操作

  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取值如下所示

  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、关闭操作

  1. int close(int fd) 
int close(int fd)


7、简单示例

效果图:





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

  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.     int fd; 
  11.    
  12.     fd = open(filename, flags, 0666); 
  13.     if (fd == -1) 
  14.         return -1; 
  15.  
  16.     return fd; 
  17.  
  18. int file_read(int fd, unsigned char *buf, int size) 
  19.      
  20.     return read(fd, buf, size); 
  21.  
  22. int file_write(int fd, const unsigned char *buf, int size) 
  23.      
  24.     return write(fd, buf, size); 
  25.  
  26.  
  27. int64_t file_seek(int fd, int64_t pos, int whence) 
  28.      
  29.     if (whence == 0x10000) { 
  30.         struct stat st; 
  31.         int ret = fstat(fd, &st); 
  32.         return ret < 0 ? -1 : st.st_size; 
  33.     } 
  34.     return lseek(fd, pos, whence); 
  35.  
  36. int file_close(int fd) 
  37.     
  38.     return close(fd); 
//fs.c
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <stdlib.h>
#include <fcntl.h>


 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);
}

  1. //jni.c 
  2. #define TAG "fs_jni" 
  3.  
  4. #include <android/log.h> 
  5. #include "jniUtils.h" 
  6.  
  7.  
  8.  
  9. static const char* const 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. jint 
  20. Java_com_conowen_fs_FsActivity_NativeFileRead(JNIEnv* env, jobject thiz,int fd,jbyteArray buf,jint size){ 
  21.  
  22.     unsigned char *buf_char = (char*)((*env)->GetByteArrayElements(env,buf, NULL)); 
  23.  
  24.     return file_read(fd, buf_char,  size); 
  25.  
  26. jint 
  27. Java_com_conowen_fs_FsActivity_NativeFileWrite(JNIEnv* env, jobject thiz,int fd,jbyteArray buf,jint size){ 
  28.      
  29.     unsigned char *buf_char = (char*)((*env)->GetByteArrayElements(env,buf, NULL)); 
  30.  
  31.     return file_write(fd, buf_char,  size); 
  32.  
  33. jlong 
  34. Java_com_conowen_fs_FsActivity_NativeFileSeek(JNIEnv* env, jobject thiz,int fd,jlong Offset,jint whence){ 
  35.  
  36.     return file_seek(fd, Offset,  whence); 
  37.  
  38. jint 
  39. Java_com_conowen_fs_FsActivity_NativeFileClose(JNIEnv* env, jobject thiz,int fd){ 
  40.  
  41.     return file_close(fd); 
  42.  
  43. /******************************JNI registration.************************************/ 
  44. static JNINativeMethod gMethods[] = { 
  45.     {"NativeFileOpen",       "(Ljava/lang/String;I)I",           (void *)Java_com_conowen_fs_FsActivity_NativeFileOpen}, 
  46.     {"NativeFileRead",       "(I[BI)I",                          (void *)Java_com_conowen_fs_FsActivity_NativeFileRead}, 
  47.     {"NativeFileWrite",      "(I[BI)I",                          (void *)Java_com_conowen_fs_FsActivity_NativeFileWrite}, 
  48.     {"NativeFileSeek",       "(IJI)J",                           (void *)Java_com_conowen_fs_FsActivity_NativeFileSeek}, 
  49.     {"NativeFileClose",      "(I)I",                             (void *)Java_com_conowen_fs_FsActivity_NativeFileClose}, 
  50. }; 
  51.  
  52. int register_com_conowen_fs_FsActivity(JNIEnv *env) { 
  53.     return jniRegisterNativeMethods(env, kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0])); 
  54.      
//jni.c
#define TAG "fs_jni"

#include <android/log.h>
#include "jniUtils.h"



static const char* const kClassPathName = "com/conowen/fs/FsActivity";


jint
Java_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);
}
jint
Java_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);
}

jint
Java_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);
}

jlong
Java_com_conowen_fs_FsActivity_NativeFileSeek(JNIEnv* env, jobject thiz,int fd,jlong Offset,jint whence){

	return file_seek(fd, Offset,  whence);
}

jint
Java_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]));
	
}



  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. #endif 
  11.  
  12. int jniThrowException(JNIEnv* env, const char* className, const char* msg); 
  13.  
  14. JNIEnv* getJNIEnv(); 
  15.  
  16. int jniRegisterNativeMethods(JNIEnv* env, 
  17.                              const char* className, 
  18.                              const JNINativeMethod* gMethods, 
  19.                              int numMethods); 
  20.  
  21. #ifdef __cplusplus 
  22. #endif 
  23.  
  24. #endif /* _JNI_UTILS_H_ */ 
//jniUtils.h
#ifndef _JNI_UTILS_H_
#define _JNI_UTILS_H_

#include <stdlib.h>
#include <jni.h>

#ifdef __cplusplus
extern "C"
{
#endif

int 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_ */

  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. static JavaVM *sVm; 
  13.  
  14. /*
  15. * Throw an exception with the specified class and an optional message.
  16. */ 
  17. int jniThrowException(JNIEnv* env, const char* className, const char* msg) { 
  18.     jclass exceptionClass = env->FindClass(className); 
  19.     if (exceptionClass == NULL) { 
  20.         __android_log_print(ANDROID_LOG_ERROR, 
  21.                 TAG, 
  22.                 "Unable to find exception class %s"
  23.                         className); 
  24.         return -1; 
  25.     } 
  26.  
  27.     if (env->ThrowNew(exceptionClass, msg) != JNI_OK) { 
  28.         __android_log_print(ANDROID_LOG_ERROR, 
  29.                 TAG, 
  30.                 "Failed throwing '%s' '%s'"
  31.                 className, msg); 
  32.     } 
  33.     return 0; 
  34.  
  35. JNIEnv* getJNIEnv() { 
  36.     JNIEnv* env = NULL; 
  37.     if (sVm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { 
  38.         __android_log_print(ANDROID_LOG_ERROR, 
  39.                             TAG, 
  40.                             "Failed to obtain JNIEnv"); 
  41.         return NULL; 
  42.     } 
  43.     return env; 
  44.  
  45. /*
  46. * Register native JNI-callable methods.
  47. *
  48. * "className" looks like "java/lang/String".
  49. */ 
  50. int jniRegisterNativeMethods(JNIEnv* env, 
  51.                              const char* className, 
  52.                              const JNINativeMethod* gMethods, 
  53.                              int numMethods) 
  54.     jclass clazz; 
  55.  
  56.     __android_log_print(ANDROID_LOG_INFO, TAG, "Registering %s natives\n", className); 
  57.     clazz = env->FindClass(className); 
  58.     if (clazz == NULL) { 
  59.         __android_log_print(ANDROID_LOG_ERROR, TAG, "Native registration unable to find class '%s'\n", className); 
  60.         return -1; 
  61.     } 
  62.     if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { 
  63.         __android_log_print(ANDROID_LOG_ERROR, TAG, "RegisterNatives failed for '%s'\n", className); 
  64.         return -1; 
  65.     } 
  66.     return 0; 
  67. //Dalvik虚拟机加载C库时,第一件事是调用JNI_OnLoad()函数 
  68. jint JNI_OnLoad(JavaVM* vm, void* reserved) { 
  69.     JNIEnv* env = NULL; 
  70.     jint result = JNI_ERR; 
  71.     sVm = vm; 
  72.  
  73.     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { 
  74.         __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv failed!"); 
  75.         return result; 
  76.     } 
  77.  
  78.     __android_log_print(ANDROID_LOG_INFO, TAG, "loading . . ."); 
  79.  
  80.  
  81.     if(register_com_conowen_fs_FsActivity(env) != JNI_OK) { 
  82.         __android_log_print(ANDROID_LOG_ERROR, TAG, "can't load register_com_conowen_fs_FsActivity"); 
  83.         goto end; 
  84.     } 
  85.  
  86.     __android_log_print(ANDROID_LOG_INFO, TAG, "loaded"); 
  87.  
  88.     result = JNI_VERSION_1_4; 
  89.  
  90. end: 
  91.     return result; 
//onLoad.cpp
#define TAG "fs_onLoad"

#include <android/log.h>
#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文件


  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    := fs
LOCAL_SRC_FILES := fs.c jni.c onLoad.cpp
LOCAL_LDLIBS  += -llog

include $(BUILD_SHARED_LIBRARY)


7.3、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.     } 
/* 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卡操作权限

  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
  2. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值