NDK 读写文本文件¶
更新日期 2021-9-1
- 2021-9-1 更新格式
- 2021-1-21 创建文档
开发环境与工具
- Android Studio 4.1.1
- NDK 20.0.*
用cpp代码实现文件的读写操作。
ndk环境搭建¶
main/cpp目录下的CMakeLists.txt,指定fisher-lib.cpp为源文件。库的名称定为fisher-lib
。
cmake_minimum_required(VERSION 3.4.1)
add_library( # Specifies the name of the library.
fisher-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
fisher-lib.cpp )
Java代码¶
新建FileUtils文件,注意包名。
package com.rustfisher.tutorial2020.ndk.util;
/**
* 文件操作功能
* 2021-1-26
*/
public class FileUtils {
static {
System.loadLibrary("fisher-lib");
}
/**
* @param filepath 文件绝对路径
*/
public native String nReadFile(String filepath);
public native void nWrite(String filepath, String msg);
}
记得加载fisher-lib
。
cpp代码¶
写好Java代码后,使用as的功能,可以很快的在cpp文件中得到方法名。
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring JNICALL
Java_com_rustfisher_tutorial2020_ndk_util_FileUtils_nReadFile(JNIEnv *env, jobject thiz,
jstring filepath) {
char *filepathPtr = const_cast<char *>(env->GetStringUTFChars(filepath, JNI_FALSE));
FILE *file = fopen(filepathPtr, "r+");
char myStr[128];
if (file != nullptr) {
char *readInPtr = fgets(myStr, 128, file);
fclose(file);
if (nullptr != readInPtr) {
return env->NewStringUTF(myStr);
}
return env->NewStringUTF("JNI read file fail!");
}
return env->NewStringUTF("JNI read file fail!");
}
extern "C"
JNIEXPORT void JNICALL
Java_com_rustfisher_tutorial2020_ndk_util_FileUtils_nWrite(JNIEnv *env, jobject thiz,
jstring filepath, jstring msg) {
char *filepathPtr = const_cast<char *>(env->GetStringUTFChars(filepath, NULL));
FILE *file = fopen(filepathPtr, "w+");
const char *nativeMsg = reinterpret_cast<const char *>(env->GetStringUTFChars(msg, NULL));
if (file != nullptr) {
fputs(nativeMsg, file);
fflush(file);
fclose(file);
}
}
运行测试¶
例如在NdkFileVm里执行操作
private final FileUtils mNdkFileUtils = new FileUtils();
String mFilepath1;
public NdkFileVm(@NonNull Application application) {
super(application);
File file = new File(application.getFilesDir(), "ndk_file1.txt");
mFilepath1 = file.getAbsolutePath();
if (file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void writeInData(View v) {
String data = "Rust Fisher. Data time " + System.currentTimeMillis();
mNdkFileUtils.nWrite(mFilepath1, data);
}
public void readData(View v) {
String data = mNdkFileUtils.nReadFile(mFilepath1);
mObData1.set(data);
}
方法记录¶
打开文件 fopen
¶
FILE * fopen(const char * path,const char * mode);
mode模式选择,例如"r"
- r(read): 读
- w(write): 写
- a(append): 追加
- t(text): 文本文件,可省略不写
- b(banary): 二进制文件
- +: 读和写
凡用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。
用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已 经存在,则将该文件删去,重建一个新文件。这个方法保证目标文件里写入的只有我们要的数据。
若要向一个已存在的文件追加新的信息,只能用“a”方式打开文件。但此时该文件必须是存在的,否则将会出错。
在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成 打开文件的工作,并作相应的处理。
如果成功的打开一个文件, fopen()函数返回文件指针, 否则返回空指针
读取文件数据 fgets
¶
char *fgets(char *s, int n, FILE *stream);
从文件指针stream中读取n-1个字符,存到以s为起始地址的空间里,直到读完一行,如果成功则返回s的指
针,否则返回NULL。
env->NewStringUTF¶
(*env)->NewStringUTF(env, char *);
如果传入的char*是一个空值,在一些平台上会报错。
比如红米手机会直接崩溃,而魅族手机能得到一个空的String。
可以参考NDK中的字符串
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~