C語言獲取文件大小的兩種方式
因為音視頻開發(fā)的需要,經(jīng)常會寫一些文件輸入輸出的測試程序,常常用到獲取文件大小的函數(shù)。本篇文章就記錄一下我常用的兩種獲取文件大小的方式。
通過文件指針獲取文件大小
文件指針 就是調(diào)用 fopen() 函數(shù)返回的指向FILE結(jié)構(gòu)體的指針,通過文件指針可以對文件進行打開、關(guān)閉、讀寫以及控制讀寫位置等操作。fopen() 就不做介紹了,這里主要說明用到的另外兩個函數(shù)。
首先是 fseek(),用來移動文件指針,fseek的用法:
int fseek(FILE *stream, long offset, int whence);
/*
函數(shù)作用:以whence為基點,設(shè)置stream的文件指針到偏移offset的位置
參數(shù)說明:
stream 文件指針
offset 相對于whence的偏移值
whence 基準位置,可設(shè)置為
SEEK_SET (0) 文件頭
SEEK_CUR (1) 當(dāng)前位置
SEEK_END (2) 文件尾
返回值:設(shè)置成功返回0;設(shè)置失敗返回-1,并設(shè)置errno的值。
*/
另一個就是ftell(),這個函數(shù)可以獲取文件指針當(dāng)前位置相對于文件頭的偏移,當(dāng)文件指針指向文件末尾時,ftell() 返回的就是文件的大小。ftell() 函數(shù)的用法:
long ftell(FILE *stream);
/*
函數(shù)作用:獲取文件指針相對于文件頭的偏移值。
參數(shù)說明:
stream 文件指針
返回值:獲取成功返回當(dāng)前偏移值;獲取失敗返回-1,并設(shè)置errno的值。
*/
通過文件指針獲取文件大小的思路,就是使用fseek將文件指針移動到文件末尾,然后使用ftell獲取文件指針相對于文件頭的偏移即可得到文件的大小。有一點需要注意,為了不影響對文件的后續(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) { // 移動文件指針到文件末尾
printf("fseek failed: %s\n", strerror(errno));
return -1;
}
file_size = ftell(stream); // 獲取此時偏移值,即文件大小
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;
}通過文件描述符獲取文件大小
文件描述符即打開(open)或創(chuàng)建(creat)文件時內(nèi)核向進程返回的非負整數(shù),內(nèi)核通過文件描述符訪問文件。通過文件描述符獲取文件大小只需要一個函數(shù) fstat, fstat可以獲取文件的狀態(tài),其中就包含文件大小的字段。
對于一個現(xiàn)有文件,一般使用 open() 獲取其文件描述符。
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
/*
函數(shù)作用:打開一個文件。
參數(shù)說明:
pathname 文件路徑及文件名
flag 打開標志,具體參考 open 函數(shù)的man-page
mode 打開模式,具體參考 open 函數(shù)的man-page
返回值:打開成功返回文件描述符;打開失敗返回-1,并設(shè)置errno的值。
*/
接下來說明 stat 結(jié)構(gòu)體和 fstat() 函數(shù)的用法:
struct stat {
dev_t st_dev; // 文件所在設(shè)備ID
ino_t st_ino; // 結(jié)點(inode)編號
mode_t st_mode; // 保護模式
nlink_t st_nlink; // 硬鏈接個數(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 塊個數(shù)
time_t st_atime; // 上次訪問時間
time_t st_mtime; // 上次更新時間
time_t st_ctime; // 上次狀態(tài)更改時間
};
int fstat(int fd, struct stat *statbuf);
/*
函數(shù)作用:獲取文件狀態(tài)。
參數(shù)說明:
fd 文件描述符
statbuf 指向文件狀態(tài)結(jié)構(gòu)體指針
返回值:獲取成功返回0;獲取失敗返回-1,并設(shè)置errno的值。
*/第一段代碼中將文件指針作為了函數(shù)的參數(shù),用于文件已使用 fopen() 打開的情況。下面的代碼將文件名做為參數(shù),用于文件未被打開的場景。
// 需要的頭文件
#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); // 打開文件
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;
}
本文主要描述了通過文件指針和文件描述符獲取文件大小的兩種方式,并且提供了兩個參考函數(shù),可以在日常工作中根據(jù)需求使用。
到此這篇關(guān)于C語言獲取文件大小的兩種方式的文章就介紹到這了,更多相關(guān)C語言獲取文件大小內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MoveWindow() SetWindowPos()的區(qū)別于聯(lián)系
這篇文章主要介紹了VC++中MoveWindow() SetWindowPos()的區(qū)別于聯(lián)系,需要的朋友可以參考下2015-01-01
VS2022設(shè)置編碼方式為utf-8的三種方式小結(jié)
本文主要介紹了VS2022設(shè)置編碼方式為utf-8的三種方式小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09

