zoukankan      html  css  js  c++  java
  • 【转】文件读写NDK(或Linux)

    原文网址:http://www.ithao123.cn/content-10709539.html

    使用NDK进行文件读写,有利于保存数据的安全性,项目需要,要文件读写从Java中处理搬到Linux平台,为了方便两个平台的代码维护一致,使用JNI进行重写编写;

    public class MainActivity extends Activity implements OnClickListener {
    
    	private String tag = getClass().getSimpleName();
    	private TextView textView;
    	private static final String filePath = "/mnt/sdcard/hello.txt";
    	private int num = 0;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		textView = (TextView) findViewById(R.id.textView);
    		findViewById(R.id.bt_add).setOnClickListener(this);
    		findViewById(R.id.bt_del).setOnClickListener(this);
    		findViewById(R.id.bt_update).setOnClickListener(this);
    		findViewById(R.id.bt_select).setOnClickListener(this);
    	}
    
    	@Override
    	public void onClick(View v) {
    		switch (v.getId()) {
    		case R.id.bt_add:
    			num++;
    			JniFileTools.writeFile(filePath, ", "+num);
    			textView.setText(JniFileTools.readFile(filePath));
    			break;
    		case R.id.bt_del:
    			JniFileTools.deleteString(filePath, ", "+num);
    			textView.setText(JniFileTools.readFile(filePath));
    			if(num > 0){
    				num--;
    			}
    			break;
    		case R.id.bt_update:
    			break;
    		case R.id.bt_select:
    			textView.setText(JniFileTools.readFile(filePath));
    			break;
    		default:
    			break;
    		}
    	}
    }

    JNI接口:

    package jni.file.tools;
    
    public class JniFileTools {
    
    	private final static String tag = "JniFileTools";
    
    	static {
    		System.loadLibrary("opfile");
    	}
    
    	public final static native String readFile(String filePath);
    
    	public final static native boolean writeFile(String filePath, String content);
    
    	public final static native boolean deleteString(String filePath,
    			String content);
    
    }
    


    实现3个方法:

    Java_jni_file_tools_JniFileTools_readFile();

    Java_jni_file_tools_JniFileTools_writeFile();

    Java_jni_file_tools_JniFileTools_deleteString();

    JniFileTools.cpp

    #include <jni.h>
    #include"JniFileTools.h"
    #include<stdlib.h>
    #include<stdio.h>
    #include<android/log.h>
    #include <stdarg.h>
    
    void Log_i(const char* log, ...) {
    	// 请引入#include <stdarg.h>
    	va_list arg;
    	va_start(arg, log);
    	__android_log_vprint(ANDROID_LOG_INFO, "JniLogTools", log, arg);
    	va_end(arg);
    }
    
    void readFromFile(char* fileName, char *str) {
    	FILE *fp;
    	int n = 0;
    	char strTemp[128];
    	fp = fopen(fileName, "r");
    	if (fp == NULL) {
    		Log_i("readFromFile打开失败");
    		return;
    	}
    	while (NULL != fgets(strTemp, sizeof(strTemp), fp)) {
    		strcat(str, strTemp);
    	}
    	fclose(fp);
    	return;
    }
    
    unsigned char writeToFile(char* fileName, char* content, const char * mode) {
    	FILE *fp;
    	fp = fopen(fileName, mode); //w+ , "a+"
    	if (fp == NULL) {
    		fclose(fp);
    		return false;
    	}
    	int length = strlen(content);
    	for (int i = 0; i < length; i++) {
    		fputc(content[i], fp);
    	}
    	fclose(fp);
    	return true;
    }
    
    char * jstringToChar(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); //new char[alen+1];
    		memcpy(rtn, ba, alen);
    		rtn[alen] = 0;
    	}
    	env->ReleaseByteArrayElements(barr, ba, 0);
    	return rtn;
    }
    
    jstring charTojstring(JNIEnv* env, const char* pat) {
    	jclass strClass = env->FindClass("Ljava/lang/String;");
    	jmethodID ctorID = env->GetMethodID(strClass, "<init>",
    			"([BLjava/lang/String;)V");
    	jbyteArray bytes = env->NewByteArray(strlen(pat));
    	env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*) pat);
    	jstring encoding = env->NewStringUTF("utf-8");
    	return (jstring) env->NewObject(strClass, ctorID, bytes, encoding);
    }
    
    char *delSubstr(char *str, char *delstr) {
    	char *p, *q;
    	char *src, *dst;
    	dst = src = str;
    	while (*src != '') {
    		p = src;
    		q = delstr;
    		while (*p == *q && *q != '') {
    			p++;
    			q++;
    		}
    		if (*q == '') {
    			src = p;
    		} else {
    			*dst++ = *src++;
    		}
    	}
    	*dst = '';
    	return str;
    }
    
    JNIEXPORT jstring JNICALL Java_jni_file_tools_JniFileTools_readFile(
    		JNIEnv * env, jclass cls, jstring filePath) {
    	char str[1024];
    	memset(str, 0, sizeof(str));
    	readFromFile(jstringToChar(env, filePath), str);
    	return (env)->NewStringUTF(str);
    }
    
    JNIEXPORT jboolean JNICALL Java_jni_file_tools_JniFileTools_writeFile(
    		JNIEnv * env, jclass cls, jstring filePath, jstring content) {
    	writeToFile(jstringToChar(env, filePath), jstringToChar(env, content),
    			"a+");
    	return true;
    }
    
    JNIEXPORT jboolean JNICALL Java_jni_file_tools_JniFileTools_deleteString(
    		JNIEnv * env, jclass cls, jstring filePath, jstring content) {
    	char str[1024];
    	memset(str, 0, sizeof(str));
    	readFromFile(jstringToChar(env, filePath), str);
    	delSubstr(str,jstringToChar(env, content));
    	writeToFile(jstringToChar(env, filePath),str,"w+");
    	return true;
    }
    

    Android.mk

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := libopfile
    LOCAL_SRC_FILES := 
    			JniFileTools.cpp
    
    LOCAL_LDLIBS :=-llog
    LOCAL_LDLIBS    += -lGLESv2 -llog -ldl
    include $(BUILD_SHARED_LIBRARY)

    注意使用权限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    本案例中涉及到有:
    1 delSubstr()删除指定字符串;
    2 jstring和char*之间的互相转换;
    3 读写模式a+和w+;
    4 封装输出日志到Logcat;

    关于fopen()函数的几个使用:

    读写方式有下列几种常用的形态:
    r 以只读方式打开文件,该文件必须存在。
    r+ 以可读写方式打开文件,该文件必须存在。
    rb+ 读写打开一个二进制文件,允许读写数据,文件必须存在。
    w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
    w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
    a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
    a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)

  • 相关阅读:
    提高你的Java代码质量吧:正确使用String、StringBuffer、StringBuilder
    IAAS云计算产品畅想-云主机产品内涵
    Boa服务器在ARM+Linux上的移植
    二叉树的遍历的迭代和递归实现方式
    OpenRisc-42-or1200的ALU模块分析
    根据不同的下拉值,出现相应的文本输入框
    boost------asio库的使用2(Boost程序库完全开发指南)读书笔记
    C++一些注意点之操作符重载
    mac下修改mysql的默认字符集为utf8
    jquery_EasyUI的学习
  • 原文地址:https://www.cnblogs.com/wi100sh/p/5191367.html
Copyright © 2011-2022 走看看