亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

詳解C++編程中對二進制文件的讀寫操作

2020-01-26 14:50:40
字體:
來源:轉載
供稿:網友

二進制文件不是以ASCII代碼存放數據的,它將內存中數據存儲形式不加轉換地傳送到磁盤文件,因此它又稱為內存數據的映像文件。因為文件中的信息不是字符數據,而是字節中的二進制形式的信息,因此它又稱為字節文件。

對二進制文件的操作也需要先打開文件,用完后要關閉文件。在打開時要用ios::binary指定為以二進制形式傳送和存儲。二進制文件除了可以作為輸入文件或輸出文件外,還可以是既能輸入又能輸出的文件。這是和ASCII文件不同的地方。
用成員函數read和write讀寫二進制文件

對二進制文件的讀寫主要用istream類的成員函數read和write來實現。這兩個成員函數的原型為

  istream& read(char *buffer,int len);  ostream& write(const char * buffer,int len);


字符指針buffer指向內存中一段存儲空間。len是讀寫的字節數。調用的方式為:

  a. write(p1,50);  b. read(p2,30);


上面第一行中的a是輸出文件流對象,write函數將字符指針p1所給出的地址開始的50個字節的內容不加轉換地寫到磁盤文件中。在第二行中,b是輸入文件流對象,read 函數從b所關聯的磁盤文件中,讀入30個字節(或遇EOF結束),存放在字符指針p2所指的一段空間內。

[例] 將一批數據以二進制形式存放在磁盤文件中。

#include <fstream>using namespace std;struct student{  char name[20];  int num;  int age;  char sex;};int main( ){  student stud[3]={"Li",1001,18,'f',"Fun",1002,19,'m',"Wang",1004,17,'f'};  ofstream outfile("stud.dat",ios::binary);  if(!outfile)  {   cerr<<"open error!"<<endl;   abort( );//退出程序  }  for(int i=0;i<3;i++)   outfile.write((char*)&stud[i],sizeof(stud[i]));   outfile.close( );  return 0;}

用成員函數write向stud.dat輸出數據,從前面給出的write函數的原型可以看出: 第1個形參是指向char型常變量的指針變量buffer,之所以用const聲明,是因為不允許通過指針改變其指向數據的值。形參要求相應的實參是字符指針或字符串的首地址。現在要將結構體數組的一個元素(包含4個成員)一次輸出到磁盤文件stud.dat。&tud[i] 是結構體數組第i個元素的首地址,但這是指向結構體的指針,與形參類型不匹配。因此 要用(char *)把它強制轉換為字符指針。第2個參數是指定一次輸出的字節數。sizeof (stud[i])的值是結構體數組的一個元素的字節數。調用一次write函數,就將從&tud[i]開始的結構體數組的一個元素輸出到磁盤文件中,執行3次循環輸出結構體數組的3個元素。

其實可以一次輸出結構體數組的個元素,將for循環的兩行改為以下一行:

  outfile.write((char*)&stud[0],sizeof(stud));


執行一次write函數即輸出了結構體數組的全部數據。

abort函數的作用是退出程序,與exit作用相同。

可以看到,用這種方法一次可以輸出一批數據,效率較高。在輸出的數據之間不必加入空格,在一次輸出之后也不必加回車換行符。在以后從該文件讀入數據時不是靠空格作為數據的間隔,而是用字節數來控制。

[例] 將剛才以二進制形式存放在磁盤文件中的數據讀入內存并在顯示器上顯示。

#include <fstream>using namespace std;struct student{  string name;  int num;  int age;  char sex;};int main( ){  student stud[3];  int i;  ifstream infile("stud.dat",ios::binary);  if(!infile)  {   cerr<<"open error!"<<endl;   abort( );  }  for(i=0;i<3;i++)  infile.read((char*)&stud[i],sizeof(stud[i]));  infile.close( );  for(i=0;i<3;i++)  {   cout<<"NO."<<i+1<<endl;   cout<<"name:"<<stud[i].name<<endl;   cout<<"num:"<<stud[i].num<<endl;;   cout<<"age:"<<stud[i].age<<endl;   cout<<"sex:"<<stud[i].sex<<endl<<endl;  }  return 0;}

運行時在顯示器上顯示:

NO.1name: Linum: 1001age: 18sex: fNO.2name: Funnum: 1001age: 19sex: mNO.3name: Wangnum: 1004age: 17sex: f

請思考,能否一次讀入文件中的全部數據,如:

  infile.read((char*)&stud[0],sizeof(stud));

答案是可以的,將指定數目的字節讀入內存,依次存放在以地址&tud[0]開始的存儲空間中。要注意讀入的數據的格式要與存放它的空間的格式匹配。由于磁盤文件中的數據是從內存中結構體數組元素得來的,因此它仍然保留結構體元素的數據格式?,F在再讀入內存,存放在同樣的結構體數組中,這必然是匹配的。如果把它放到一個整型數組中,就不匹配了,會出錯。
與文件指針有關的流成員函數

在磁盤文件中有一個文件指針,用來指明當前應進行讀寫的位置。在輸入時每讀入 一個宇節,指針就向后移動一個字節。在輸出時每向文件輸出一個字節,指針就向后移動 一個字節,隨著輸出文件中字節不斷增加,指針不斷后移。對于二進制文件,允許對指針進行控制,使它按用戶的意圖移動到所需的位置,以便在該位置上進行讀寫。文件流提供 一些有關文件指針的成員函數。為了查閱方便,將它們歸納為下表:

幾點說明:
1) 這些函數名的第一個字母或最后一個字母不是g就是p。帶 g的是用于輸入的函數(g是get的第一個字母,以g作為輸入的標識,容易理解和記憶), 帶p的是用于輸出的函數(P是put的第一個字母,以P作為輸出的標識)。例如有兩個 tell 函數,tellg用于輸入文件,tellp用于輸出文件。同樣,seekg用于輸入文件,seekp用于輸出文件。以上函數見名知意,一看就明白,不必死記。

如果是既可輸入又可輸出的文件,則任意用seekg或seekp。

2) 函數參數中的“文件中的位置”和“位移量”已被指定為long型整數,以字節為單位?!皡⒄瘴恢谩笨梢允窍旅嫒咧唬?br />    ios::beg  文件開頭(beg是begin的縮寫),這是默認值。
    ios::cur  指針當前的位置(cur是current的縮寫)。
    ios::end  文件末尾。
它們是在ios類中定義的枚舉常量。舉例如下:
    infile.seekg(100);  //輸入文件中的指針向前移到字節位置
    infile.seekg(-50,ios::cur);  //輸入文件中的指針從當前位置后移字節
    outfile.seekp(-75,ios::end);  //輸出文件中的指針從文件尾后移字節
隨機訪問二進制數據文件

一般情況下讀寫是順序進行的,即逐個字節進行讀寫。但是對于二進制數據文件來說,可以利用上面的成員函數移動指針,隨機地訪問文件中任一位置上的數據,還可以修改文件中的內容。

[例] 有個學生的數據,要求:
把它們存到磁盤文件中;
將磁盤文件中的第,3,5個學生數據讀入程序,并顯示出來;
將第個學生的數據修改后存回磁盤文件中的原有位置。
從磁盤文件讀入修改后的個學生的數據并顯示出來。

要實現以上要求,需要解決個問題:
由于同一磁盤文件在程序中需要頻繁地進行輸入和輸出,因此可將文件的工作方式指定為輸入輸出文件,即ios::in|ios::out|ios::binary。
正確計算好每次訪問時指針的定位,即正確使用seekg或seekp函數。
正確進行文件中數據的重寫(更新)。

可寫出以下程序:

#include <fstream>using namespace std;struct student{  int num;  char name[20];  float score;};int main( ){  student stud[5]={1001,"Li",85,1002,"Fun",97.5,1004,"Wang",54,1006,"Tan",76.5,1010,"ling",96};  fstream iofile("stud.dat",ios::in|ios::out|ios::binary);  //用fstream類定義輸入輸出二進制文件流對象iofile  if(!iofile)  {   cerr<<"open error!"<<endl;   abort( );  }  for(int i=0;i<5;i++) //向磁盤文件輸出個學生的數據   iofile.write((char *)&stud[i],sizeof(stud[i]));  student stud1[5]; //用來存放從磁盤文件讀入的數據  for(int i=0;i<5;i=i+2)  {   iofile.seekg(i*sizeof(stud[i]),ios::beg); //定位于第,2,4學生數據開頭   //先后讀入個學生的數據,存放在stud1[0],stud[1]和stud[2]中   iofile.read((char *)&stud1[i/2],sizeof(stud1[0]));   //輸出stud1[0],stud[1]和stud[2]各成員的值   cout<<stud1[i/2].num<<" "<<stud1[i/2].name<<" "<<stud1[i/2].score<<endl;  }  cout<<endl;  stud[2].num=1012; //修改第個學生(序號為)的數據  strcpy(stud[2].name,"Wu");  stud[2].score=60;  iofile.seekp(2*sizeof(stud[0]),ios::beg); //定位于第個學生數據的開頭  iofile.write((char *)&stud[2],sizeof(stud[2])); //更新第個學生數據  iofile.seekg(0,ios::beg); //重新定位于文件開頭  for(int i=0;i<5;i++)  {   iofile.read((char *)&stud[i],sizeof(stud[i])); //讀入個學生的數據   cout<<stud[i].num<<" "<<stud[i].name<<" "<<stud[i].score<<endl;  }  iofile.close( );  return 0;}

運行情況如下:

1001 Li 85(第個學生數據)1004 Wang 54    (第個學生數據)1010 ling 96    (第個學生數據)1001 Li 85     (輸出修改后個學生數據)1002 Fun 97.51012 Wu 60     (已修改的第個學生數據)1006 Tan 76.51010 ling 96

本程序也可以將磁盤文件stud.dat先后定義為輸出文件和輸入文件,在結束第一次的輸出之后關閉該文件,然后再按輸入方式打開它,輸入完后再關閉它,然后再按輸出方式打開,再關閉,再按輸入方式打開它,輸入完后再關閉。顯然這是很煩瑣和不方便的。 在程序中把它指定為輸入輸出型的二進制文件。這樣,不僅可以向文件添加新的數據或讀入數據,還可以修改(更新)數據。利用這些功能,可以實現比較復雜的輸入輸出任務。

請注意,不能用ifstream或ofstream類定義輸入輸出的二進制文件流對象,而應當用fstream類。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品一区二区性色av| 欧美大胆在线视频| 亚洲精品国产精品自产a区红杏吧| 日韩中文有码在线视频| 国产成人精品综合| 国产精品久久999| 国产在线观看91精品一区| 国产成人精品电影久久久| 日韩免费观看高清| 日韩成人在线免费观看| 国产午夜精品全部视频播放| 国产精品黄色av| 91精品视频在线免费观看| 日韩在线中文字幕| 亚洲国产古装精品网站| 91久久精品一区| 91精品国产免费久久久久久| 日本一区二区不卡| 亚洲精品第一国产综合精品| 日本成人免费在线| 91福利视频在线观看| 国产在线播放不卡| 日韩乱码在线视频| 精品亚洲一区二区三区在线观看| 最近2019中文免费高清视频观看www99| 青青草一区二区| 91精品国产自产在线| 欧美国产日韩在线| 久久久亚洲影院| 97视频免费观看| 自拍偷拍亚洲区| 精品成人国产在线观看男人呻吟| 在线播放日韩av| 国产精品视频99| 亚洲色图综合网| 91精品国产91久久久久久最新| 日本91av在线播放| 亚洲第一黄色网| 91欧美精品午夜性色福利在线| 久久久免费在线观看| 国产精品女主播| 91在线|亚洲| 国产精品69精品一区二区三区| 久久久久久999| 国产欧美日韩丝袜精品一区| 亚洲一区二区少妇| 欧美中文字幕精品| 国产婷婷成人久久av免费高清| 久久久久国产精品免费| 欧美日韩国产在线看| 国产这里只有精品| 国产网站欧美日韩免费精品在线观看| 国产日韩欧美91| 欧美xxxx18性欧美| 成人午夜高潮视频| 国产精品久久999| 国产精品678| 欧美日韩国产中文精品字幕自在自线| 国产精品久久久久久久7电影| 国产精品久久久久久久久久久久久| 国产精品久久在线观看| 97色在线观看| 57pao国产成人免费| 日韩成人在线电影网| 国产精品视频精品| 激情懂色av一区av二区av| 亚洲一区中文字幕在线观看| 91高清视频免费| 国产精品成人av在线| 456国产精品| 高清日韩电视剧大全免费播放在线观看| 色诱女教师一区二区三区| 久久视频这里只有精品| 亚洲精品美女免费| 成人午夜在线视频一区| 国产精品久久一| 欧美成年人视频网站欧美| 精品成人国产在线观看男人呻吟| 97人洗澡人人免费公开视频碰碰碰| 亚洲视屏在线播放| 久久九九精品99国产精品| 久久视频国产精品免费视频在线| 欧美日韩亚洲天堂| 亚洲国产99精品国自产| 少妇av一区二区三区| 91国产美女视频| 国产99久久精品一区二区| 国产精品成人免费电影| 国产欧美日韩免费看aⅴ视频| 国产精自产拍久久久久久蜜| 综合网中文字幕| 久久亚洲欧美日韩精品专区| 国产欧美精品日韩| 国模视频一区二区| 国产精品视频一区国模私拍| 91精品在线影院| 91高清免费视频| 97超碰色婷婷| 成人国产精品色哟哟| 日韩免费高清在线观看| 性夜试看影院91社区| 日韩国产高清污视频在线观看| 亚洲少妇激情视频| 国产精品电影观看| 青青草原成人在线视频| 26uuu另类亚洲欧美日本一| 日韩精品一区二区视频| 国产成人精品在线视频| 国产精品美女在线观看| 国产a级全部精品| 久久成人这里只有精品| 最新亚洲国产精品| 国产精品男女猛烈高潮激情| 国产一区二区三区欧美| 7777精品久久久久久| 亚洲摸下面视频| 欧美日韩在线免费观看| 色综合久久天天综线观看| 91久久精品国产91久久| 日韩欧中文字幕| 激情av一区二区| 国产日韩欧美91| 亚洲精品久久久久久久久久久| 日韩视频在线免费| 色综合久久精品亚洲国产| 国产精品一区二区久久国产| 揄拍成人国产精品视频| 国产精品久久综合av爱欲tv| 国产高清在线不卡| 91av中文字幕| 欧美精品久久一区二区| 91在线视频一区| 国产一区av在线| 日本亚洲欧洲色α| 中文亚洲视频在线| 91国产在线精品| 少妇高潮 亚洲精品| 久久久久久久久久久人体| 国产成人福利网站| 热久久这里只有精品| 国产日韩欧美成人| 亚洲国产精品大全| 欧美在线不卡区| 精品国产乱码久久久久久婷婷| 亚洲欧美日韩天堂一区二区| 黑人极品videos精品欧美裸| 日韩中文在线不卡| 一区二区欧美亚洲| 国内伊人久久久久久网站视频| 亚洲精品国精品久久99热一| 97在线视频国产| 亚洲欧美综合v| 久久这里只有精品99| 国产专区精品视频| 亚洲性无码av在线| 亚洲欧美日韩精品久久奇米色影视| 亚洲性日韩精品一区二区| 国产视频久久久久| 91最新在线免费观看| 中文字幕免费精品一区高清| www.欧美三级电影.com| 97av视频在线| 人人做人人澡人人爽欧美| 日韩国产激情在线|