接續(xù)上篇C語言基礎(chǔ)及指針⑦結(jié)構(gòu)體與指針
在結(jié)構(gòu)體與指針中 , 我們了解到結(jié)構(gòu)體與java中的類相似 劈伴, 也是一種自定義類型數(shù)據(jù)結(jié)構(gòu) 劲藐, 也學(xué)習(xí)了結(jié)構(gòu)的各種用法 告希, 以及簡單的應(yīng)用 。
在編寫應(yīng)用程序的時(shí)候 引矩, 文件IO操作是不可避免的 梁丘, 小到日志本地化收集 , 大到數(shù)據(jù)格式化存儲 旺韭, 都需要使用文件IO 兰吟, 來操作文件流進(jìn)行數(shù)據(jù)處理 。在使用java開發(fā)的時(shí)候 茂翔, 我們有File
類和FileReader
,FileWriter
類來搭配使用 混蔼, 也有FileInputStream
,FileOutputStream
和BufferedInputStream
,BufferedOutputStream
金牌組合 。使得java中的文件IO很方便 珊燎, 下面我們就來看看簡單的java文件IO示例:
// 讀取文件中的字符
private static void readString() throws Exception{
File _file = new File("e:"+separetor+"a.txt") ;
if (!_file.exists()) {
boolean createStatuts = _file.createNewFile() ;
if (createStatuts) {
System.out.println("創(chuàng)建了一個(gè)新文件 惭嚣,并且創(chuàng)建成功了");
}else {
System.out.println("創(chuàng)建新文件失敗");
}
}
// 創(chuàng)建輸入流
InputStream fileInputStream = new FileInputStream(_file) ;
byte[] bytes = new byte[1024] ;
int len = -1;
StringBuffer buffer = new StringBuffer() ;
while ((len = fileInputStream.read(bytes)) != -1) {
buffer.append(new String(bytes,0,len)) ;
}
// 關(guān)閉輸入流
fileInputStream.close() ;
System.out.println(buffer.toString());
}
// 將字符串寫入文件
private static void writeString() throws Exception{
File _file = new File("e:"+separetor+"a.txt") ;
if (!_file.exists()) {
boolean createStatuts = _file.createNewFile() ;
if (createStatuts) {
System.out.println("創(chuàng)建了一個(gè)新文件 遵湖,并且創(chuàng)建成功了");
}else {
System.out.println("創(chuàng)建新文件失敗");
}
}
// 創(chuàng)建輸出流
OutputStream fileOutputStream = new FileOutputStream(_file) ;
String info = "《op 青空 pure rouge 君吻》《君吻 その目に映るもの piano》" ;
fileOutputStream.write(info.getBytes()) ;
// 關(guān)閉輸出流
fileOutputStream.close() ;
}
文件IO操作步驟:
1.創(chuàng)建一個(gè)File對象(需要操作的文件)
2.構(gòu)建輸入輸出流
3.創(chuàng)建緩沖區(qū) , 緩存讀寫數(shù)據(jù) (將流數(shù)據(jù)讀入到內(nèi)存或?qū)懭氲酱疟P)
3.關(guān)閉流 (關(guān)閉文件流)
語言都是相通的 晚吞, 在C語言中文件IO的操作也是如上述幾步 延旧, 下面我們就一起來看看:
/*讀取文本文件*/
void readTextFile() {
char* path = "C:\\Users\\Zeno\\Documents\\Visual Studio 2015\\Projects\\Hello_C\\Hello_C\\StructPointer.c";
// 打開文件
FILE* fp = fopen(path, "r");
if (fp == NULL)
{
printf("打開文件失敗\n");
return;
}
// 字符緩沖區(qū) , 每次讀一個(gè)字符串 槽地, 都會緩存到字符數(shù)組中
char buffer[1024];
while (fgets(buffer, 1024, fp)) {
printf("%s", buffer);
}
// 關(guān)閉文件流
fclose(fp);
/*寫入文本文件*/
void writeTextFile() {
char* path = "E:\\document\\write.txt";
char* content = "如果 愛情是一場花火 ,一閃即逝的花火,我也要去追求\n如果 愛情是一場花火 ,一閃即逝的花火,我也要去追求\n";
// 打開文件
/*
打開只寫文件迁沫,若文件存在則文件長度清為0,即該文件內(nèi)容會消失捌蚊。若文件不存在則建立該文件集畅。
*/
FILE* fp = fopen(path, "w");
if (fp == NULL)
{
printf("打開文件失敗\n");
return;
}
// 寫入文件
fputs(content, fp);
// 關(guān)閉文件流
fclose(fp);
}
}
首先使用fopen
函數(shù)得到一個(gè)文件指針 , 操作符r
為讀取文件流 缅糟, 構(gòu)建了一個(gè)buffer
數(shù)據(jù)緩沖區(qū) 挺智, 通過fgets
函數(shù)循環(huán)讀取文件數(shù)據(jù) , fclose
函數(shù)關(guān)閉文件流 窗宦。在操作文件IO的時(shí)候 赦颇, 最重要的函數(shù) , 莫過于fopen
函數(shù)了 赴涵, 首先我們來看一下fopen
函數(shù)的定義:
_ACRTIMP FILE* __cdecl fopen(
_In_z_ char const* _FileName,
_In_z_ char const* _Mode
);
我們發(fā)現(xiàn)fopen
函數(shù) 媒怯, 需要傳入文件全路徑名稱 , 還有一個(gè)_Mode
髓窜, 這個(gè)是文件操作模式 沪摄, C語言中文件操作主要依靠操作模式來辨別是輸入流還是輸出流的 。
下面列舉一些常用的操作模式:
mode有下列幾種形態(tài)字符串:
r 打開只讀文件纱烘,該文件必須存在杨拐。
r+ 打開可讀寫的文件,該文件必須存在擂啥。
w 打開只寫文件哄陶,若文件存在則文件長度清為0,即該文件內(nèi)容會消失哺壶。若文件不存在則建立該文件屋吨。
w+ 打開可讀寫文件,若文件存在則文件長度清為零山宾,即該文件內(nèi)容會消失至扰。若文件不存在則建立該文件。
a 以附加的方式打開只寫文件资锰。若文件不存在敢课,則會建立該文件,如果文件存在,寫入的數(shù)據(jù)會被加到文件尾直秆,即文件原先的內(nèi)容會被保留濒募。
a+ 以附加方式打開可讀寫的文件。若文件不存在圾结,則會建立該文件瑰剃,如果文件存在,寫入的數(shù)據(jù)會被加到文件尾后筝野,即文件原先的內(nèi)容會被保留晌姚。
值得注意的是 , 上述操作模式是針對文本文件的 歇竟, 如果要操作二進(jìn)制文件 挥唠, 則需要在上述操作符后面加上b
, 如rb
,wb
,ab
途蒋, 等等 。
不論是文本文件的操作還是字符文件的操作 馋记, 都是 号坡, 打開文件 , 創(chuàng)建緩沖區(qū) 梯醒, 讀寫文件 宽堆。
二進(jìn)制文件讀寫
/*讀寫二進(jìn)制文件 -- 復(fù)制文件*/
void fileCopy() {
char* currentPath = "E:\\android_pdf\\研磨設(shè)計(jì)模式.pdf";
char* destPath = "E:\\android_pdf\\研磨設(shè)計(jì)模式_new.pdf";
// 打開文件
FILE* currentFile_P = fopen(currentPath, "rb");
FILE* destFile_P = fopen(destPath, "wb");
// 先讀取再寫入
int buffer[1024]; // 數(shù)據(jù)緩沖區(qū)
int len; // 每次讀取數(shù)據(jù)的長度
while ((len = fread(buffer,sizeof(int),1024,currentFile_P)) != EOF)
{
// 將緩沖區(qū)里的內(nèi)容寫入到文件中
fwrite(buffer, sizeof(int), len, destFile_P);
}
// 關(guān)閉流
fclose(destFile_P);
fclose(currentFile_P);
}
讀寫二進(jìn)制和讀寫文本文件沒多少區(qū)別 , 最大的區(qū)別就是fopen
函數(shù)中的模式的不同 茸习, 文本文件是r
,w
畜隶, 二進(jìn)制文件是rb
,wb
。
了解了文件IO的基本操作 号胚, 我們使用文件IO流寫一個(gè)加密解密的小程序籽慢。我們知道 , 所有的文件都是以二進(jìn)制存儲的 猫胁, 我們看的文本文件箱亿, 圖片文件 , 視頻文件 弃秆, 都是以二進(jìn)制存儲在磁盤上的 届惋, 那么 , 我們可以將文件讀取出來 菠赚, 進(jìn)行二進(jìn)制運(yùn)算 脑豹, 就可以將文件加密解密了 。下面我們通過^
異或運(yùn)算來進(jìn)行文件的加密解密 衡查, 異或運(yùn)算的規(guī)則如下:
0 ^ 1 得 1
1 ^ 1 得 0
0 ^ 0 得 0
1 ^ 0 得 1
相同為0 不同為1 , 例如 瘩欺, 我們將4
這個(gè)數(shù)加密 , 異或的數(shù)是5 , 下面我們來看看運(yùn)算:
4的二進(jìn)制是:0100
5的二進(jìn)制是:0101
異或運(yùn)算結(jié)果(加密):4 ^ 5 == 0001
異或運(yùn)算結(jié)果(解密): 0001 ^ 0101 == 0100
由上述可見 击碗, ^一次為加密 筑悴, 再^一次就是解密
代碼示例如下:
文件加密
/*加密文件*/
void encryptFile() {
// 待加密文件路徑
char* normal_path = "E:\\poto\\xj.jpg";
// 加密后文件路徑
char* encrypt_path = "E:\\poto\\xj_encrypt.jpg";
//打開文件
FILE* normal_fp = fopen(normal_path, "rb");
FILE* encrypt_fp = fopen(encrypt_path, "wb");
// 讀文件
int buffer;
while ((buffer = fgetc(normal_fp)) != EOF) {
// 寫入文件
fputc(buffer ^ 8, encrypt_fp);
}
printf("文件加密成功\n");
// 關(guān)閉流
fclose(encrypt_fp);
fclose(normal_fp);
}
文件解密
/*文件解密*/
void decryptFile() {
// 加密文件路徑
char* encrypt_path = "E:\\poto\\xj_encrypt.jpg";
// 解密文件路徑
char* decrypt_path = "E:\\poto\\xj_deencrypt.jpg";
// 打開文件
FILE* encrypt_fp = fopen(encrypt_path, "rb");
FILE* decrypt_fp = fopen(decrypt_path, "wb");
// 讀取文件
int buffer;
while ((buffer = fgetc(encrypt_fp)) != EOF) {
// 寫文件
fputc(buffer ^ 8, decrypt_fp);
}
printf("文件解密成功\n");
// 關(guān)閉流
fclose(decrypt_fp);
fclose(encrypt_fp);
}
了解了文件加密的原理 , 我們也可以推導(dǎo)出其他形式的加密 稍途, 如帶密碼的文件加密解密 阁吝, 混合文件加密解密等等 。
不知不覺C語言基礎(chǔ)系列已經(jīng)寫了快十篇了 械拍, 也快告一段落了 突勇, 有了這些基礎(chǔ)知識 , 我們就可以去分析分析jni.h頭文件了 坷虑, 下一個(gè)系列是jni開發(fā)系列 甲馋, 我們學(xué)C語言就是為了能和java打交道 , 那么下個(gè)系列我們就來學(xué)習(xí)C與java的橋梁 迄损, jni (Java Native Interface)技術(shù) 定躏。
Android程序員學(xué)C系列:
C語言基礎(chǔ)及指針①
C語言基礎(chǔ)及指針②之指針內(nèi)存分析
C語言基礎(chǔ)及指針③函數(shù)與二級指針
C語言基礎(chǔ)及指針④函數(shù)指針
C語言基礎(chǔ)及指針⑤動態(tài)內(nèi)存分配
C語言基礎(chǔ)及指針⑥字符操作
C語言基礎(chǔ)及指針⑦結(jié)構(gòu)體與指針
C語言基礎(chǔ)及指針⑧文件IO
C語言基礎(chǔ)及指針⑨聯(lián)合體與枚舉
C語言基礎(chǔ)及指針⑩預(yù)編譯及jni.h分析