C語(yǔ)言獲取文件大小的兩種方式
因?yàn)橐粢曨l開(kāi)發(fā)的需要,經(jīng)常會(huì)寫(xiě)一些文件輸入輸出的測(cè)試程序,常常用到獲取文件大小的函數(shù)。本篇文章就記錄一下我常用的兩種獲取文件大小的方式。
通過(guò)文件指針獲取文件大小
文件指針 就是調(diào)用 fopen() 函數(shù)返回的指向FILE結(jié)構(gòu)體的指針,通過(guò)文件指針可以對(duì)文件進(jìn)行打開(kāi)、關(guān)閉、讀寫(xiě)以及控制讀寫(xiě)位置等操作。fopen() 就不做介紹了,這里主要說(shuō)明用到的另外兩個(gè)函數(shù)。
首先是 fseek(),用來(lái)移動(dòng)文件指針,fseek的用法:
int fseek(FILE *stream, long offset, int whence); /* 函數(shù)作用:以whence為基點(diǎn),設(shè)置stream的文件指針到偏移offset的位置 參數(shù)說(shuō)明: stream 文件指針 offset 相對(duì)于whence的偏移值 whence 基準(zhǔn)位置,可設(shè)置為 SEEK_SET (0) 文件頭 SEEK_CUR (1) 當(dāng)前位置 SEEK_END (2) 文件尾 返回值:設(shè)置成功返回0;設(shè)置失敗返回-1,并設(shè)置errno的值。 */
另一個(gè)就是ftell(),這個(gè)函數(shù)可以獲取文件指針當(dāng)前位置相對(duì)于文件頭的偏移,當(dāng)文件指針指向文件末尾時(shí),ftell() 返回的就是文件的大小。ftell() 函數(shù)的用法:
long ftell(FILE *stream); /* 函數(shù)作用:獲取文件指針相對(duì)于文件頭的偏移值。 參數(shù)說(shuō)明: stream 文件指針 返回值:獲取成功返回當(dāng)前偏移值;獲取失敗返回-1,并設(shè)置errno的值。 */
通過(guò)文件指針獲取文件大小的思路,就是使用fseek將文件指針移動(dòng)到文件末尾,然后使用ftell獲取文件指針相對(duì)于文件頭的偏移即可得到文件的大小。有一點(diǎn)需要注意,為了不影響對(duì)文件的后續(xù)操作,需要記錄文件指針的初始位置,并在函數(shù)退出前將文件指針恢復(fù)到初始位置。封裝為函數(shù)如下:
long get_file_size(FILE *stream) { long file_size = -1; long cur_offset = ftell(stream); // 獲取當(dāng)前偏移位置 if (cur_offset == -1) { printf("ftell failed :%s\n", strerror(errno)); return -1; } if (fseek(stream, 0, SEEK_END) != 0) { // 移動(dòng)文件指針到文件末尾 printf("fseek failed: %s\n", strerror(errno)); return -1; } file_size = ftell(stream); // 獲取此時(shí)偏移值,即文件大小 if (file_size == -1) { printf("ftell failed :%s\n", strerror(errno)); } if (fseek(stream, cur_offset, SEEK_SET) != 0) { // 將文件指針恢復(fù)初始位置 printf("fseek failed: %s\n", strerror(errno)); return -1; } return file_size; }
通過(guò)文件描述符獲取文件大小
文件描述符即打開(kāi)(open)或創(chuàng)建(creat)文件時(shí)內(nèi)核向進(jìn)程返回的非負(fù)整數(shù),內(nèi)核通過(guò)文件描述符訪問(wèn)文件。通過(guò)文件描述符獲取文件大小只需要一個(gè)函數(shù) fstat, fstat可以獲取文件的狀態(tài),其中就包含文件大小的字段。
對(duì)于一個(gè)現(xiàn)有文件,一般使用 open() 獲取其文件描述符。
int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); /* 函數(shù)作用:打開(kāi)一個(gè)文件。 參數(shù)說(shuō)明: pathname 文件路徑及文件名 flag 打開(kāi)標(biāo)志,具體參考 open 函數(shù)的man-page mode 打開(kāi)模式,具體參考 open 函數(shù)的man-page 返回值:打開(kāi)成功返回文件描述符;打開(kāi)失敗返回-1,并設(shè)置errno的值。 */
接下來(lái)說(shuō)明 stat 結(jié)構(gòu)體和 fstat() 函數(shù)的用法:
struct stat { dev_t st_dev; // 文件所在設(shè)備ID ino_t st_ino; // 結(jié)點(diǎn)(inode)編號(hào) mode_t st_mode; // 保護(hù)模式 nlink_t st_nlink; // 硬鏈接個(gè)數(shù) uid_t st_uid; // 所有者用戶ID gid_t st_gid; // 所有者組ID dev_t st_rdev; // 設(shè)備ID(如果是特殊文件) off_t st_size; // 總體尺寸,以字節(jié)為單位 blksize_t st_blksize; // 文件系統(tǒng) I/O 塊大小 blkcnt_t st_blocks; // 已分配 512B 塊個(gè)數(shù) time_t st_atime; // 上次訪問(wèn)時(shí)間 time_t st_mtime; // 上次更新時(shí)間 time_t st_ctime; // 上次狀態(tài)更改時(shí)間 }; int fstat(int fd, struct stat *statbuf); /* 函數(shù)作用:獲取文件狀態(tài)。 參數(shù)說(shuō)明: fd 文件描述符 statbuf 指向文件狀態(tài)結(jié)構(gòu)體指針 返回值:獲取成功返回0;獲取失敗返回-1,并設(shè)置errno的值。 */
第一段代碼中將文件指針作為了函數(shù)的參數(shù),用于文件已使用 fopen() 打開(kāi)的情況。下面的代碼將文件名做為參數(shù),用于文件未被打開(kāi)的場(chǎng)景。
// 需要的頭文件 #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> off_t get_file_size(char *file_name) { int ret; int fd = -1; struct stat file_stat; fd = open(file_name, O_RDONLY); // 打開(kāi)文件 if (fd == -1) { printf("Open file %s failed : %s\n", file_name, strerror(errno)); return -1; } ret = fstat(fd, &file_stat); // 獲取文件狀態(tài) if (ret == -1) { printf("Get file %s stat failed:%s\n", file_name, strerror(errno)); close(fd); return -1; } close(fd); return file_stat.st_size; }
本文主要描述了通過(guò)文件指針和文件描述符獲取文件大小的兩種方式,并且提供了兩個(gè)參考函數(shù),可以在日常工作中根據(jù)需求使用。
到此這篇關(guān)于C語(yǔ)言獲取文件大小的兩種方式的文章就介紹到這了,更多相關(guān)C語(yǔ)言獲取文件大小內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MoveWindow() SetWindowPos()的區(qū)別于聯(lián)系
這篇文章主要介紹了VC++中MoveWindow() SetWindowPos()的區(qū)別于聯(lián)系,需要的朋友可以參考下2015-01-01C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易停車場(chǎng)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易停車場(chǎng)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03VS2022設(shè)置編碼方式為utf-8的三種方式小結(jié)
本文主要介紹了VS2022設(shè)置編碼方式為utf-8的三種方式小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09二叉樹(shù)中葉子節(jié)點(diǎn)的統(tǒng)計(jì)和樹(shù)高問(wèn)題
今天小編就為大家分享一篇關(guān)于二叉樹(shù)中葉子節(jié)點(diǎn)的統(tǒng)計(jì)和樹(shù)高問(wèn)題,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03