NDK文件读写记录
一、开发中的问题记录
1.自己定义一个函数,函数返回string,但是 直接return "xxxx"; 时,显示语法出错,原因:"xxxx" 这是不是string,这是char[], 所以不能直接写 return "xxxx";可以
string txt = "xxxx";
return txt;这样写。
2.fopen("xxxx","w+"); fopen函数用于打开文件,参数一表示文件的绝对地址,参数二表示打开模式。其中"w+"表示以读写双模式打开文件。但是实验中发现,在直接读文件时,使用"w+"将读取不到文件,是因为文件数据没有加载进缓冲区。如果先写入,在读取,则能读到数据。
3.fread不是专门用于字符串读写的函数。fread读取数据易发生乱码(无论中英文,均会乱码),个人尚无解决方法,不建议使用。同时建议使用fgets();
4.fclose是用于关闭文件。其中得注意 文件读写时,不会立即写入到文件,会先写入到缓冲区。然后在fflush和fclose操作时才会写入到文件。同时我认为fclose应该会回收内存,但是为了安全起见,我还是写上delete file,这并不会导致程序异常。
5.env->NewStringUTF(txt.data()); 注:当txt中出现乱码时,NewStringUTF就会发生异常。然后程序崩溃。
6.EOP值为-1;
7.fscanf格式化读取数据,为固定格式读取数据。返回读取到想项目数。同时读取数据时,参数出错可能无法读取,或数据乱码。建议在占位符(如:%s)前后添加空格,否则会导致不能正常格式化读取数据
二、学习时编写的代码
2、文件读写之 fwrite、fread
#include "com_xcc_app3_MyJni.h"
#include <string>
#include <android/log.h>
#include <stdio.h>
using namespace std;//定义命名空间,string使用
#define LOG_TAG "--xcc-native-dev--"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
void Java_com_xcc_app3_MyJni_fileW(JNIEnv * env, jclass
jc){//写入
FILE *file=fopen("/data/data/com.xcc.app3/jniRW.txt","w+");
/**
* 注:w只读,w+读写双模式
* 双模式下,在读写转化时,需要先调用fflush 刷新缓冲区
*/
if(NULL==file){
LOGI("--文件打开失败--");
}else{
LOGI("--文件打开成功--");
//string str="--这是磁磁帅写入的文件数据--";
string str="--this is cicishuai write file data--";
int len=str.length();
char p[len+1];
for(int i=0;i<str.length();i++)
p[i] = str[i];
p[len] = '\0';
if(len!=fwrite(p,sizeof(char),len,file)){
LOGI("--文件写入出错--长度:%d",len);
}else LOGI("--文件写入成功--");
if(0!=fclose(file)){
LOGI("--文件关闭失败--");
}else LOGI("--文件关闭成功--");
delete file;
/**
* 注:文件读写时,不会立即写入到文件
* 会先写入到缓冲区,
* fflush和fclose操作时才会写入到文件
*/
}
}
jstring Java_com_xcc_app3_MyJni_fileR(JNIEnv * env, jclass
jc){//读取
/**
* 注:读取文件时应当使用"r+",
* 使用"w+"时,可能出现读取不到数据
*/
FILE *file=fopen("/data/data/com.xcc.app3/jniRW.txt","r+");
if(NULL==file){
LOGI("--文件打开失败--");
}else{
LOGI("--文件打开成功--");
int len=10;
char p[len+1];
string txt="";
LOGI("--开始读取文件--");
/**
* 注:fread读取数据易发生乱码,个人尚无解决方法,不建议使用
* 建议使用fgets();
* fread不是用于字符串读写函数
*/
for(int idx=fread(p,sizeof(char),len,file);idx>0;idx=fread(p,sizeof(char),len,file)){
p[idx+1]='\0';//这条是用于解决乱码的,但是没有任何效果
string sTmp=p;
txt+=sTmp;
LOGI("--当前读取到的内容-->%s",txt.data());//注:此处需要的是 *string 即 char[],所以得传txt.data()
}
LOGI("--读取字符串结束,内容:-->%s",txt.data());
if(0!=fclose(file)){
LOGI("--文件关闭失败--");
}else LOGI("--文件关闭成功--");
delete file;//我认为fclose应该会回收内存,但是为了安全起见,我还是写上delete
/**
* 注:当txt中出现乱码时,NewStringUTF就会发生异常。
* 然后程序崩溃
*/
//return env->NewStringUTF(txt.data());
}
return env->NewStringUTF("磁磁帅->文件数据读取失败");
}
2、文件读写之 fputs、fgets
#include "com_xcc_app3_MyJni2.h"
#include <string>
#include <android/log.h>
#include <stdio.h>
using namespace std;
#define LOG_TAG "--xcc-native-dev--"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
void Java_com_xcc_app3_MyJni2_fileW(JNIEnv * env, jclass
jc){//写入
FILE *file=fopen("/data/data/com.xcc.app3/jniRW2.txt","w+");
if(NULL==file){
LOGI("--文件打开失败--");
}else{
LOGI("--文件打开成功--");
string str="--这是磁磁帅写入的文件数据--";
//string str="--this is cicishuai write file data--";
LOGI("EOF:%d",EOF);//实验得出,EOP为-1;
if(EOF==fputs(str.data(),file)){
LOGI("--文件写入出错--");
}else LOGI("--文件写入成功--");
if(0!=fclose(file)){
LOGI("--文件关闭失败--");
}else LOGI("--文件关闭成功--");
delete file;
}
}
jstring Java_com_xcc_app3_MyJni2_fileR(JNIEnv * env, jclass
jc){//读取
FILE *file=fopen("/data/data/com.xcc.app3/jniRW2.txt","r+");
if(NULL==file){
LOGI("--文件打开失败--");
}else{
LOGI("--文件打开成功--");
int len=10;
char p[len];
string txt="";
LOGI("--开始读取文件--");
for(;NULL!=fgets(p,len,file);){
txt+=p;
LOGI("--当前读取到的内容-->%s",txt.data());
}
LOGI("--读取字符串结束,内容:-->%s",txt.data());
if(0!=fclose(file)){
LOGI("--文件关闭失败--");
}else LOGI("--文件关闭成功--");
delete file;
return env->NewStringUTF(txt.data());
}
return env->NewStringUTF("磁磁帅->文件数据读取失败");
}
3、文件读写之 fputc、fgetc And fprintf、fscanf
#include "com_xcc_app3_MyJni3.h"
#include <string>
#include <android/log.h>
#include <stdio.h>
using namespace std;
#define LOG_TAG "--xcc-native-dev--"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
void charFileW() {//字符方式写入文件
FILE *file = fopen("/data/data/com.xcc.app3/jniRW3.txt", "w+");
if (NULL == file) {
LOGI("--文件打开失败--");
} else {
LOGI("--文件打开成功--");
string str = "--这是磁磁帅写入的文件数据--";
//string str="--this is cicishuai write file data--";
int len = str.length();
const char *cs;
cs = str.data();
for (int idx = 0; idx < len; idx++) {
if (EOF == fputc(cs[idx], file)) {
LOGI("--文件写入出错--");
break;
}
else
LOGI("--文件写入字符成功--");
}
if (0 != fclose(file)) {
LOGI("--文件关闭失败--");
} else
LOGI("--文件关闭成功--");
delete file;
}
}
void printFileW(){//格式化写入文件
FILE *file = fopen("/data/data/com.xcc.app3/jniRW4.txt", "w+");
if (NULL == file) {
LOGI("--文件打开失败--");
} else {
LOGI("--文件打开成功--");
//string str="--this is cicishuai write file data--";
/**
* 注:需要在%s前后添加空格,否则会导致不能正常格式化读取数据
*/
if(0>fprintf(file,"--这是 %s 写入的文件数据 %d --","磁磁帅",1111)){
LOGI("--写入数据出错--");
}
if (0 != fclose(file)) {
LOGI("--文件关闭失败--");
} else
LOGI("--文件关闭成功--");
delete file;
}
}
void Java_com_xcc_app3_MyJni3_fileW(JNIEnv * env, jclass
jc){//写入
LOGI("--字符方式写入文件-->");
charFileW();
LOGI("--格式化数据写入文件-->");
printFileW();
}
string charFileR() {//字符方式读文件
FILE *file = fopen("/data/data/com.xcc.app3/jniRW3.txt", "r+");
string txt = "";
if (NULL == file) {
LOGI("--文件打开失败--");
} else {
LOGI("--文件打开成功--");
char tmpC[1];
for (char retInt = fgetc(file); ; retInt = fgetc(file)) {
if (EOF == retInt) {
LOGI("--读文件出错 或 读取文件结束--");
break;
}
tmpC[0] = retInt;
txt += tmpC;
LOGI("--当前读取到的内容-->%s", txt.data());
}
if (0 != fclose(file)) {
LOGI("--文件关闭失败--");
} else
LOGI("--文件关闭成功--");
delete file;
return txt;
}
/**
* 注:此处返回string,
* 但是 "xxxx" 这是不是string,这是char[];
* 所以不能直接写 return "xxxx";
*/
txt = "磁磁帅->文件数据读取失败";
return txt;
}
string printFileR() {//格式化读文件
FILE *file = fopen("/data/data/com.xcc.app3/jniRW4.txt", "r+");
string txt = "";
if (NULL == file) {
LOGI("--文件打开失败--");
} else {
LOGI("--文件打开成功--");
string str = "--这是 %s 写入的文件数据 %d --";
int i;
char ch[9];
/**
* fscanf返回的是读取到的项目数
* 此处2表示读取2个项目。
*/
if(2!=fscanf(file,str.data(),ch,&i)){
LOGI("--读文件出错--");
}else{
txt=ch;
LOGI("--读取到的数据[%s][%d]--",ch,i);
return txt;
}
}
txt = "磁磁帅->文件数据读取失败";
return txt;
}
jstring Java_com_xcc_app3_MyJni3_fileR(JNIEnv * env, jclass
jc){//读取
LOGI("--字符方式读文件-->");
string cString=charFileR();
LOGI("--格式化读文件-->");
cString+=printFileR();
return env->NewStringUTF(cString.data());
}
学习时编写的完整代码,下载地址:
码云:http://git.oschina.net/rookieci/NDKStudy
github:https://github.com/cookieci/NDKStudy