我的NDK學習開發筆記(二)

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






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章