C語言中文件定位函數主要是:fseek, ftell, fsetpos, fgetpos。
先來講前兩個函數,這是最基本的定位函數:
fseek函數:能把文件指針移動到文件任何位置,其原型是:int fseek(FILE *fp, long offset, int fromwhere);
參數解釋:第一個參數為要進行定位的文件的指針;第二個參數為定位的偏移量,一個有符號的long類型值,正數表示文件指針向后偏移,負數表示文件指針向前偏移,0 表示不進行偏移;第三個參數表示文件指針從哪個位置開始偏移,有三個值可選,SEEK_SET & SEEK_CUR & SEEK_END,分別表示文件第一個字節(即第零個位置),文件指針當前所指字節(即當前位置)和文件EOF位置。
返回值:返回 0 表示操作成功,返回非 0 表示操作失敗。
其他注意:該函數不能定位到第一個字節之前的位置,如果嘗試這樣操作會導致fseek返回 -1,即操作失敗,比如這樣的代碼“j = fseek(fp, -4L, SEEK_SET );”,其中 j 值就是 -1;但是,該函數能定位到EOF位置之后的位置,並且不報錯,即使這樣是沒有意義的,比如這樣的代碼“j = fseek(fp, 4L, SEEK_END)”,返回值 j 是 0,並且此時 ftell(fp) 返回值是SEEK_END + 4。
ftell函數:能返回當前文件指針所在的位置(文件的第一個字節所在位置是零),其原型是:long ftell(FILE *fp);
參數解釋:有且僅有一個參數,為一個文件的指針。
返回值:有符號long類型的正向值,即0~2147483647。
其他注意:暫無。
實際上,前兩個函數對文件指針的定位雖然都很方便,但是它們都有一個局限性,那就是它們能定位的最大字節是依據 long 類型的取值范圍決定。比如 fseek(fp, max_pos, SEEK_SET);,它能移動的最大偏移量是 max_pos = 2147483647字節,即1GB,對於大於1GB的文件來說就力不從心了。
所以ANSI C推出了解決大文件定位的方案,即后兩個函數!(不過,即使是現在,直接處理一個超過1G的單文件還是比較少的)
在說這兩個函數之前,先要介紹一個數據類型fpos_t,它是一個結構體類型,保存着文件指針的位置,並且這種數據類型只能被fgetpos和fsetpos函數使用。
fsetpos函數:將文件指針的位置設置為fpos_t類型變量所保存的位置,其原型是:int fsetpos(FILE *, const fpos_t *)
參數解釋:第一個參數為一個文件的指針;第二個參數為一個fpos_t類型的指針。
返回值:0 表示操作成功,非 0 表示操作失敗。
其他注意:暫無。
fgetpos函數:將文件指針的位置保存到fpos_t類型變量中,其原型是:int fgetpos(FILE *, fpos_t *)
參數解釋:同fsetpos。
返回值:同fsetpos。
其他注意:暫無。
總結:后兩個函數通常是fseek函數偏移累加之后超過long范圍時才用到,例如如下代碼:
fpos_t pos; //定義一個fpos_t類型的變量pos f = fopen("a.txt", "r"); //假設a.txt是一個超過1G的文件 fseek(f, 2000000000L, SEEK_SET); //向后偏移20億字節 fseek(f, 1000000000L, SEEK_CUR); //再向后面偏移10億字節 //此時,文件指針的位置已經超過了signed long的正向范圍,就需要用fpos_t類型變量來保存文件指針位置了 fgetpos(f, &pos); //此時,當前文件指針的位置已保存到pos變量中了 fseek(f, 5000L, SEEK_CUR); printf("%x\n", getc(f)); //再向后偏移5千字節,並取出偏移后所在的字節,以十六進制打印出來 fsetpos(f, &pos); //利用fsetpos函數重置文件指針,根據最后一次fgetpos保存的pos值,這次函數操作將向前偏移5千字節 printf("%x\n", getc(f)); //以十六進制打印出當前字節 fclose(f); //釋放文件流
上述代碼可能有點抽象,因為你可能一時間找不到大於1G的文件,那么我們就用小文件來演示一下:
假設文件"utf8.txt"的十六進制結構如下:
41 42 43 56 57 44 44 4B
C語言代碼如下:
FILE * f1; fpos_t pos; f1 = fopen("utf8.txt", "r"); fseek(f1,2,SEEK_SET); fgetpos(f1, &pos); fseek(f1,4,SEEK_SET); printf("%x\n", getc(f1)); fsetpos(f1,&pos); printf("%x\n", getc(f1)); fclose(f1);
輸出結果:
57
43
Press any key to continue
