原文网址: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. ASP.NET html转图片

    using System.IO; using System.Drawing; using System.Threading; using System.Windows.Forms; public cl ...

  2. CakePHP之请求与响应对象

    请求与响应对象 请求与响应对象在 CakePHP 2.0 是新增加的.在之前的版本中,这两个对象是由数组表示的,而相关的方法是分散在RequestHandlerComponent,Router,Dis ...

  3. 详细查看数据库SQL执行计划

    DBCC DROPCLEANBUFFERS 清除数据缓存DBCC FREEPROCCACHE  清除执行计划缓存 SET SHOWPLAN_XML ON 此语句导致 SQL Server 不执行 Tr ...

  4. ASP.NET 导入EXCEL文档

    鉴于教务一般都是手动输入学生信息,在未了解本校数据库的客观情况之下,我们准备设计一个导入excel文档中学生信息如数据库的功能.结合网上各类大牛的综合版本出炉.. 首先具体的实现思想如下: 1.先使用 ...

  5. java问题整理

    1.一个“.java”源文件中是否可以包括多个类(不是内部类)?有什么限制? 答:可以有多个类.但只能有一个public类.并且public类名必须与文件名相一致.   2.Java有没有goto? ...

  6. 226. Invert Binary Tree(C++)

    226. Invert Binary Tree Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 ...

  7. cuda中时间用法

    转载:http://blog.csdn.net/jdhanhua/article/details/4843653 在CUDA中统计运算时间,大致有三种方法: <1>使用cutil.h中的函 ...

  8. 『重构--改善既有代码的设计』读书笔记----Introduce Foreign Method

    当你无法获得一个类的源代码或者没有权限去修改这个类的时候,你对于这种为你服务的类,你可能会出现需要别的需求的时候,比如一个Date类,你需要能够让他本身直接返回出他的后一天的对象,但他没有,这个时候你 ...

  9. 3 - testng.xml

    TestNG的调用有以下几种方式: testng.xml ant 命令行 这部分主要介绍testng.xml的格式. 当前testng.xml的DTD(文档类型定义(Document Type Def ...

  10. UNIX 系统上的文本操作简介

    http://www.oschina.net/question/129540_53561 UNIX 的基本哲学之一就是创建只做一件事并将这一件事做好的程序(或进程).这一哲学要求认真考虑接口以及结合这 ...