原文网址: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 != '\0') {
p = src;
q = delstr;
while (*p == *q && *q != '\0') {
p++;
q++;
}
if (*q == '\0') {
src = p;
} else {
*dst++ = *src++;
}
}
*dst = '\0';
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符不保留)

【转】文件读写NDK(或Linux)的更多相关文章

  1. python文件读写操作与linux shell变量命令交互执行

    python对文件的读写还是挺方便的,与linux shell的交互变量需要转换一下才能用,这比较头疼! #coding=utf-8 #!/usr/bin/python import os impor ...

  2. Linux文件读写机制及优化方式

    导读 Linux是一个可控性强的,安全高效的操作系统.本文只讨论Linux下文件的读写机制,不涉及不同读取方式如read,fread,cin等的对比,这些读取方式本质上都是调用系统api read,只 ...

  3. (转)linux文件读写的流程

    转自http://hi.baidu.com/_kouu/item/4e9db87580328244ef1e53d0 在<linux内核虚拟文件系统浅析>这篇文章中,我们看到文件是如何被打开 ...

  4. Linux高级编程--05.文件读写

    缓冲I/O和非缓冲I/O 文件读写主要牵涉到了如下五个操作:打开.关闭.读.写.定位.在Linux系统中,提供了两套API, 一套是C标准API:fopen.fclose.fread.fwrite.f ...

  5. Linux Direct 文件读写(文件DIO)

    有时候,读写文件并不想要使用系统缓存(page cache),此时 direct 文件读写就派上了用场,使用方法: (1)打开文件时,添加O_DIRECT参数: 需要定义_GNU_SOURCE,否则找 ...

  6. Linux C 文件与目录3 文件读写

    文件读写 文件读写是指从文件中读出信息或将信息写入到文件中.Linux文件读取可使用read函数来实现的,文件写入可使用write函数来实现.在进行文件写入的操作时,只是在文件的缓冲区中操作,可能没有 ...

  7. Linux 文件读写操作与磁盘挂载

    文件读写 [文件描述符] Linux下,通常通过open打开一个文件,它然后返回给我们一个整数,通过这个整数便可以操作文件,这个整数我们称文件描述符(fd).对应被打开的文件,它也是一种系统资源,那么 ...

  8. Linux环境下实现对文件读写操作

    ---- 今天分享一下在linux系统在实现对文件读写一些基本的操作,在这之前我们要掌握一些基本的技能在Linux环境下.比如查看命令和一个函数的具体用法,就是相当于查手册,在Linux下有一个man ...

  9. 从 Linux 内核角度探秘 JDK NIO 文件读写本质

    1. 前言 笔者在 <从 Linux 内核角度看 IO 模型的演变>一文中曾对 Socket 文件在内核中的相关数据结构为大家做了详尽的阐述. 又在此基础之上介绍了针对 socket 文件 ...

随机推荐

  1. Android(java)学习笔记199:Android中补间动画(Tween Animation)

    本文主要简单介绍补间动画使用代码实现, 关于使用xml实现补间动画,可以参看:自定义控件三部曲之动画篇(一)——alpha.scale.translate.rotate.set的xml属性及用法 1. ...

  2. Objective-C:swift、objective-c、C++、C混合编程

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...

  3. c# 双问号运算

    model.id??0 ??运算:如果运算符左边的值为NULL侧返回右边的值,否则返回左边的值

  4. Uploadify 笔记分享 -- 2014年10月18日

    最近要做一个项目,有个部分需要用到Uploadify,以前用过,但不是很懂,找了无数遍的中文文档,发现好多都是以前的,都不能用,一时间索性自己写了个笔记,随用随查 <form> <i ...

  5. 数据挖掘经典书籍[ZZ]

    数据挖掘就是在数据库中查找所需数据的过程,它是随着数据库产生的一门学科.近几年,数据库的发展还是非常迅速的,数据挖掘也成为热门技术,学习的人络绎不绝.下面给大家介绍的就是数据挖掘经典书籍及数据挖掘书籍 ...

  6. Linux下su与su -命令的区别

    在启动服务器ntpd服务时遇到一个问题 使用 su root 切换到root用户后,不可以使用service命令: 使用 su - 后,就可以使用service命令了. 原因: su命令和su -命令 ...

  7. sicily-2499 平方数

    题目分析: 一个数可以表示成四种状态,所以可以用一个状态数组来存放该数由几个数的平方和表示.1.表示该数本身是完全平方.2.表示该数是由两个平方和3.表示三个.4.表示4个.一次遍历找出本身是完全平方 ...

  8. java中如何操作数据库(增删改查)

    EntityManager 是用来对实体Bean 进行操作的辅助类.他可以用来产生/删除持久化的实体Bean,通过主键查找实体bean,也可以通过EJB3 QL 语言查找满足条件的实体Bean.实体B ...

  9. Ubuntu14 或是其他系统当中关于sublimeSFTP超时解决方法

    一直都使用Sublime的SFTP功能,感觉还不错,好用,但是最近不知道怎么了,使用不成了,提示超时了,于是在网上找一下解决方法,没有找到,于是自己想着试试看,于在搞了一会,发现只要把配制文件当中的s ...

  10. 如何让同一个字段在不同的view中显示不同的内容

    many2one 字段默认显示 对象的name字段, 但也可以定义name_get方法显示不同的内容 如res.partner 对象可以根据 context 内容是否显示 客户的地址,职位,email ...