接續上篇C語言基礎及指針⑧文件IO
在上篇中 , 我們初步了解了C語言的IO操作 , 編寫IO操作的大致流程:
文件IO編寫步驟:
1.使用fopen
函數 , 得到文件指針
2.指定fopen
的操作模式r
,w
(指定輸入輸出流)
3.創建緩沖區 , 緩存讀寫數據(將流數據讀入到內存或寫入到磁盤)
3.關閉流 (關閉文件流)
接著介紹了文件的加密解密 , 文件的存儲都是以二進制保存在磁盤上的 , 所以我們可以通過二進制運算來進行文件的加密解密操作 。在C語言的IO函數中 , 沒有直接獲取文件大小的函數 , 所以我們需要自己通過文件指針來獲取文件的大小:
/*獲取文件大小*/
void getFileSize() {
char* path = "E:\\android_pdf\\研磨設計模式.pdf";
// 打開文件
FILE* fp = fopen(path, "r");
if (fp == NULL) {
printf("打開文件失敗\n");
return;
}
// 重新定位文件指針 , SEEK_END文件末尾,0是文件指針的偏移量
fseek(fp, 0l, SEEK_END);
// 返回當前的文件指針,相對于文件開頭的位移量
long fileSize = ftell(fp);
printf("文件大小:%ld M\n", fileSize / 1024 / 1024);
}
在jni.h中 , 我們可以看到這樣一段代碼:
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
這樣C語言中的聯合體 , 那么什么是聯合體呢 ?
聯合體:不同類型的變量共用一段內存(相互覆蓋) , 始終只有一個成員存在 , 最后賦值的那個 , 有利于節省內存。
聯合體大小:成員中最大的成員所占的字節數
聯合體 , 將不同的類型聯合起來 , 組成一個新的聚合類型 , 這個類型可以是聯合體中的任意類型 。
/*聯合體*/
/*
不同類型的變量共用一段內存(相互覆蓋) , 始終只有一個成員存在 , 最后賦值的那個 , 有利于節省內存
聯合體大小:成員中最大的成員所占的字節數
*/
union mValue
{
int i;
short s;
long l;
float f;
};
/*聯合體示例*/
void useUnion() {
union mValue m;
m.f = 23.4f;
m.i = 100; // 最后一次賦值有效
printf("聯合體:\n%f - %d\n", m.f, m.i);
}
在java中 , 當我們需要一個類列舉幾個狀態時 , 因為狀態是固定的 , 所以我們通常的做法是使用枚舉 , 將狀態列舉出來 , 在C語言也有枚舉這個類型:
/*
枚舉(列舉所有的情況)
限定值,保證取值的安全性
*/
enum NetStatus {
NET_SUCEESS,
NET_ERROR,
NOT_NET,
NET_FAILURE
};
下面我們來看一個示例 , 來大致了解一下枚舉的使用場景:
/*枚舉*/
/*
枚舉(列舉所有的情況)
限定值,保證取值的安全性
*/
enum NetStatus {
NET_SUCEESS,
NET_ERROR,
NOT_NET,
NET_FAILURE
};
/*模擬網絡請求*/
void requestHttp(char* url, void(*callBack)(enum NetStatus status,char* res)) {
printf("請求地址:%s\n", url);
printf("請求網絡....\n");
Sleep(2000);
enum NetStatus status = NET_SUCEESS;
char* res = "如果 愛情是一場花火 ,一閃即逝的花火,我也要去追求\n";
callBack(status, res);
}
/*網絡回調函數*/
void callBackHttp(enum NetStatus status, char* res) {
switch (status)
{
case NET_SUCEESS:
printf("網絡數據:\n%s", res);
break;
case NET_ERROR:
printf("請求網絡錯誤\n");
break;
case NOT_NET:
printf("沒有網絡\n");
break;
case NET_FAILURE:
printf("請求網絡失敗\n");
break;
default:
printf("未知錯誤\n");
break;
}
}
/*枚舉示例*/
void useEnum() {
enum NetStatus status = NET_FAILURE;
printf("枚舉中元素的值:%d\n", status);
char* url = "http://www.zhuyongit.com";
requestHttp(url, callBackHttp);
}
我們模擬了網絡請求的幾種情況 , 成功 , 失敗 , 錯誤等等 , 通過枚舉將這些情況列舉出來 ,然后通過網絡回調函數傳遞到網絡處理函數 , 通過switch
分支語句來進行不同網絡狀態的判斷 。
在jni.h頭文件中 , 我們也可以見到類似的應用:
typedef enum jobjectRefType {
JNIInvalidRefType = 0,
JNILocalRefType = 1,
JNIGlobalRefType = 2,
JNIWeakGlobalRefType = 3
} jobjectRefType;
使用枚舉來標識對象引用的類型 , 本地引用,全局引用,弱引用,等等 ,因為我們在使用jni調取java對象的時候 , java虛擬機并沒有將引用數加1 , 所以我們需要用過加強引用類型 , 來保證jni引用的java對象,不被虛擬機回收掉 。
在IT的路上 , 山路崎嶇 , 山崖陡峭 , 自學如在荊棘滿布的叢林中 , 披荊斬棘 , 在渾濁的河流中 , 摸著石頭過河 。何以保證我們走的是正確的方向 , 長沙動腦學院 , 老司機眾多 , 功力深厚 , 開車穩當 , 都是互聯網老兵 , 他們是IT路上的探頭燈 , 幫你指明方向 , 帶你超神 , 他們的宗旨是:做一家受人尊敬的企業,做一位受人尊敬的老師【動腦學院】。 --- 特約贊助
Android程序員學C系列:
C語言基礎及指針①
C語言基礎及指針②之指針內存分析
C語言基礎及指針③函數與二級指針
C語言基礎及指針④函數指針
C語言基礎及指針⑤動態內存分配
C語言基礎及指針⑥字符操作
C語言基礎及指針⑦結構體與指針
C語言基礎及指針⑧文件IO
C語言基礎及指針⑨聯合體與枚舉
C語言基礎及指針⑩預編譯及jni.h分析