首先是用C語言實現:
我們一共要用到三個函數,fopen,fread,fwrite。二進制讀寫的順序是用fopen以二進制方式打開讀寫文件,然後使用fread和fwrite兩個函數將數據寫入二進制文件中。下面我們看看一個拷貝程序的源碼: ( Copy.c )
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 1024
int main(int argc, char *argv[]){
if ( argc < 3 ) {
printf("usage: %s %s/n", argv[0], "infile outfile");
exit(1);
}
FILE * outfile, *infile;
outfile = fopen(argv[2], "wb" );
infile = fopen(argv[1], "rb");
unsigned char buf[MAXLEN];
if( outfile == NULL || infile == NULL ) {
printf("%s, %s", argv[1], "not exit/n");
exit(1);
}
int rc;
while( (rc = fread(buf,sizeof(unsigned char), MAXLEN,infile)) != 0 ) {
fwrite( buf, sizeof( unsigned char ), rc, outfile );
}
fclose(infile);
fclose(outfile);
system("PAUSE");
return 0;
後面是關於fopen,fread,fwrite三個函數的詳細說明。
相關函數
|
open,fclose
|
表頭文件
|
#include<stdio.h>
|
定義函數
|
FILE * fopen(const char * path, const char * mode);
|
函數說明
|
參數path字符串包含欲打開的文件路徑及文件名,參數mode字符串則代表着流形態。
mode有下列幾種形態字符串: r : 打開只讀文件,該文件必須存在。 r+ : 打開可讀寫的文件,該文件必須存在。 w : 打開只寫文件,若文件存在則文件長度清爲0,即該文件內容會消失。若文件不存在則建立該文件。 w+ : 打開可讀寫文件,若文件存在則文件長度清爲零,即該文件內容會消失。若文件不存在則建立該文件。 a : 以附加的方式打開只寫文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾,即文件原先的內容會被保留。 a+ : 以附加方式打開可讀寫的文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾後,即文件原先的內容會被保留。 上述的形態字符串都可以再加一個b字符,如rb、w+b或ab+等組合,加入b 字符用來告訴函數庫打開的文件爲二進制文件,而非純文字文件。不過在POSIX系統,包含Linux都會忽略該字符。由fopen()所建立的新文件會具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)權限,此文件權限也會參考umask值。 |
返回值
|
文件順利打開後,指向該流的文件指針就會被返回。若果文件打開失敗則返回NULL,並把錯誤代碼存在errno 中。
|
附加說明
|
一般而言,開文件後會作一些文件讀取或寫入的動作,若開文件失敗,接下來的讀寫動作也無法順利進行,所以在fopen()後請作錯誤判斷及處理。
|
範例
|
#include<stdio.h>
main() { FILE * fp; fp=fopen("noexist", "a+"); if( fp == NULL) return; fclose(fp); } |
相關函數
|
fopen,fwrite,fseek,fscanf
|
表頭文件
|
#include<stdio.h>
|
定義函數
|
size_t fread(void * ptr, size_t size, size_t nmemb, FILE * stream);
|
函數說明
|
fread()用來從文件流中讀取數據。參數stream爲已打開的文件指針,參數ptr 指向欲存放讀取進來的數據空間,讀取的字符數以參數size*nmemb來決定。Fread()會返回實際讀取到的nmemb數目,如果此值比參數nmemb 來得小,則代表可能讀到了文件尾或有錯誤發生,這時必須用feof()或ferror()來決定發生什麼情況。
|
返回值
|
返回實際讀取到的nmemb數目。
|
附加說明
|
|
範例
|
#include<stdio.h>
#define nmemb 3 struct test { char name[20]; int size; }s[nmemb]; main() { FILE * stream; int i; stream = fopen("/tmp/fwrite", "r"); fread(s, sizeof(struct test), nmemb, stream); fclose(stream); for(i=0; i<nmemb; i++) printf("name[%d]=%-20s:size[%d]=%d/n", i, s[i].name, i, s[i].size); } |
執行
|
name[0]=Linux! size[0]=6
name[1]=FreeBSD! size[1]=8 name[2]=Windows2000 size[2]=11 |
相關函數
|
fopen,fread,fseek,fscanf
|
表頭文件
|
#include<stdio.h>
|
定義函數
|
size_t fwrite(const void * ptr, size_t size, size_t nmemb, FILE * stream);
|
函數說明
|
fwrite()用來將數據寫入文件流中。參數stream爲已打開的文件指針,參數ptr 指向欲寫入的數據地址,總共寫入的字符數以參數size*nmemb來決定。Fwrite()會返回實際寫入的nmemb數目。
|
返回值
|
返回實際寫入的nmemb數目。
|
範例
|
#include<stdio.h>
#define set_s (x,y) {strcoy(s[x].name,y);s[x].size=strlen(y);} #define nmemb 3 struct test { char name[20]; int size; }s[nmemb]; main() { FILE * stream; set_s(0, "Linux!"); set_s(1, "FreeBSD!"); set_s(2, "Windows2000."); stream=fopen("/tmp/fwrite", "w"); fwrite(s, sizeof(struct test), nmemb, stream); fclose(stream); } |
執行
|
參考fread()。
|
下面是用C++實現二進制文件的讀寫:
本文讀寫文件均使用文件流進行操作,主要使用的類是ifstream, ofstream, 使用時,請務必包含文件fstream。如下:
#include <fstream>
寫二進制文件:
寫二進制文件應該使用ofstream類,文件的打開模式一定要是 binary,如果傳入的不是 binary, 文件將以ASCII方式打開。
下面是示例代碼,用於寫入文件。
std::ofstream fout("a.dat", std::ios::binary);
int nNum = 20;
std::string str("Hello, world");
fout.write((char*)&nNum, sizeof(int));
fout.write(str.c_str(), sizeof(char) * (str.size()));
fout.close();
而寫文本文件則比較簡單,如下:
std::ofstream fout("b.dat");
int nNum = 20;
std::string str("Hello, world");
fout << nNum << "," << str << std::endl;
fout.close();
讀二進制文件:
讀取二進制文件可以使用ifstream 類來進行,文件的打開模式一定要是 binary,如果傳入的不是 binary, 文件將以ASCII方式打開。
下面是示例代碼:
std::ifstream fin("a.dat", std::ios::binary);
int nNum;
char szBuf[256] = {0};
fin.read((char*)&nNum, sizeof(int));
fin.read(szBuf, sizeof(char) * 256);
std::cout << "int = " << nNum << std::endl;
std::cout << "str = " << szBuf << std::endl;
fin.close();
而讀取文本文件則比較簡單:
std::ifstream fin("b.dat");
int nNum;
char szBuf[256] = {0};
fin >> nNum >> szBuf;
std::cout << "int = " << nNum << std::endl;
std::cout << "str = " << szBuf << std::endl;
fin.close();
文件的打開模式:
文件操作時,如果不顯示指定打開模式,文件流類將使用默認值。
在<fstream> 中定義瞭如下打開模式和文件屬性:
ios::app // 從後面添加
ios::ate // 打開並找到文件尾
ios::binary // 二進制模式I/O(與文本模式相對)
ios::in // 只讀打開
ios::out // 寫打開
ios::trunc // 將文件截爲 0 長度
可以使用位操作符 OR 組合這些標誌,比如
ofstream logFile("log.dat", ios::binary | ios::app);
二進制文件的複製:
這裏我實現了一個二進制文件的複製操作,用於驗證讀寫的正確性,示例代碼如下:
後記
由於文本文件本質上也是磁盤上的一個個二進制編碼,因此,讀寫二進制文件的代碼同樣可以讀寫文本文件,在文件類型不是很明確的讀寫操作中,直接使用二進制讀寫比較可取,如果可以直接判斷文件類型,則可以分別對待。
關於讀取文本文件,請參照http://blog.csdn.net/lightlater/archive/2011/04/15/6326338.aspx