如何修改文件中間的幾個字節


工作中碰到一個問題,如何只修改文件中間的幾個字節,而其他的內容不變。這個問題看似簡單,但是很多人估計都不知道怎么做。我開始seek到文件的特定的位置,然后寫文件,但是使用的文件打開模式不對,文件不是被清空,就是被截斷,達不到效果。

fopen的打開模式

在C語言中文件打開方式有這么幾種:

  • r   以只讀方式打開文件,只能讀不能寫,往文件中寫是沒有任何效果的
  • r+  可以讀,也可以寫,文件打開的時候,指向文件開頭,可以通過seek改變讀寫位置
  • w  這種方式打開的文件句柄,只能寫,如果文件存在則將長度清零,否則新建文件,這種句柄通過seek之后,seek位置之前的文件數據全部變成0x00
  • w+ 同w選項,只不過多了一個可讀功能
  • a  這種方式打開的文件,可以寫,但是位置在文件末尾,即使往回seek也沒有用,數據還是從文件末尾開始附加
  • a+ 同a選項,多了可讀的功能

另外還有2個選項,可以與上面的6個選項復合使用,一個是t表示以文本的方式打開文件(默認是t),一個是b表示以二進制的方式打開文件,t和b是互斥的不能同時使用。當與b組合時,有這么幾種方式:wb、ab、rb、wb+、ab+、rb+,而a,w,r這幾個選項是不能組合使用的,其中a,w都表示寫文件,只不過一個在文件尾,一個在文件開始處,r表示讀文件。我試過將a,w,r幾個兩兩組合使用,發現下面的現象:

  • wr 與w效果一樣
  • rw與r效果一樣
  • aw與a效果一樣
  • wa 與w效果一樣
  • ar與a效果一樣
  • ra與r效果一樣

可以看出來當a,w,r在一起組合使用的時候,其后面的選項實際上好像是被忽略了

問題的解決方法:rb+打開文件

所以解決文章開頭提出來的問題,應該使用  rb+ 的方式打開文件,這種方式打開的文件,可讀,可寫,打開之后寫指針在文件開始處,可以任意seek,而seek之后寫的內容會覆蓋被寫的內容,其他沒有寫到的內容不會有改變。

測試程序

//程序測試結果在ubuntu linux下運行獲得
#include <stdio.h>
#include <string.h> 
int main()
{
   //文件原始數據
   //00 01 02 03 04 05 06 07 08 09

   //下面每一個fopen前面注釋中的數據是以該方式打開文件,寫文件之后文件的內容
	 
   //00 00 00 00 CC DD
   //FILE * file = fopen("./test.data","wb+");
   
   //00 00 00 00 CC DD
   //FILE * file = fopen("./test.data","wb");
   
   //00 01 02 03 CC DD 06 07 08 09
   FILE * file = fopen("./test.data","rb+"); //這種是正確的做法
   
   //00 01 02 03 04 05 06 07 08 09
   //FILE * file = fopen("./test.data","rb");
   
   //00 01 02 03 04 05 06 07 08 09 CC DD
   //FILE * file = fopen("./test.data","ab");
   
   //00 01 02 03 04 05 06 07 08 09 CC DD
   //FILE * file = fopen("./test.data","ab+");
   
   //00 00 00 00 CC DD
   //FILE * file = fopen("./test.data","wr");
   
   //00 01 02 03 04 05 06 07 08 09
   //FILE * file = fopen("./test.data","rw");
   
   //00 01 02 03 04 05 06 07 08 09 CC DD
   //FILE * file = fopen("./test.data","aw");
   
   //00 00 00 00 CC DD
   //FILE * file = fopen("./test.data","wa");
   
   //00 01 02 03 04 05 06 07 08 09 CC DD
   //FILE * file = fopen("./test.data","ar");
   
   //00 01 02 03 04 05 06 07 08 09
   //FILE * file = fopen("./test.data","ra");
   if(file!=NULL)
   {
      char buffer[]={0xCC,0xDD};
      fseek(file,4,SEEK_SET);
      fwrite(buffer,1,sizeof(buffer),file);
      fclose(file);
   } 
   return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM