C++通过文件指针获取文件大小
Posted 人生海海 山山而川
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++通过文件指针获取文件大小相关的知识,希望对你有一定的参考价值。
1. 叙述
对于读取本地文件,很多时候需要预先知道本地文件的大小在进行读取。网上给出的方案是移动文件指针,计算文件头和文件尾的偏移,计算出文件的大小。但是我总觉得这样做可能会与读取文件一样消耗性能,为了解决这个问题,我写了如下例子验证了一下。
#include <iostream>
#include <fstream>
#include<Windows.h>
using namespace std;
class CTimer
{
public:
CTimer(void);
~CTimer(void);
int time_in();
double time_out();
private:
LARGE_INTEGER litmp;
LONGLONG qt1, qt2;
double dft, dff, dfm;
};
CTimer::CTimer(void)
{
}
CTimer::~CTimer(void)
{
}
int CTimer::time_in()
{
QueryPerformanceFrequency(&litmp);//获得时钟频率
dff = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);//获得初始值
qt1 = litmp.QuadPart;
return 1;
}
double CTimer::time_out()
{
QueryPerformanceCounter(&litmp);//获得终止值
qt2 = litmp.QuadPart;
dfm = (double)(qt2 - qt1);
dft = dfm / dff;//获得对应的时间值
return dft;
}
int main()
{
string file_name = "D:/Work/test.zip";
CTimer timer;
ifstream ifs(file_name, std::ios::binary | std::ios::in);
if (!ifs.is_open())
{
return 0;
}
timer.time_in();
ifs.seekg(0, std::ios::end);
int len = ifs.tellg();
ifs.seekg(0, std::ios::beg);
cout << "获取文件长度耗时:" << timer.time_out() << "秒" << endl;
timer.time_in();
char *buff = new char[len];
ifs.read(buff, len);
delete[]buff;
timer.time_out();
cout << "读取文件耗时:" << timer.time_out() << "秒" << endl;
return 1;
}
如上所示,我写了一个计时器,分别统计偏移文件指针计算文件长度与读取整个文件的耗时,运行结果如下:
2. 结论
可以看到,偏移文件指针带来的时间消耗非常小,几乎可以忽略不记。通过这个方法,不仅可以很快计算文件长度,还可以根据需要读取文件的特定位置,从而达到节省性能的目的。
C 语言文件操作 ( ftell 函数 | 使用 ftell 函数获取当前指针位置 | 通过 ftell 计算文件大小 )
一、ftell 函数
ftell()
函数的作用是 获取文件的 当前指针位置 相对于 文件首地址 的 偏移字节数 ;
ftell 函数原型 :
#include <stdio.h>
long ftell(FILE *stream);
ftell 使用场景 : 随机方式存取文件时 , 使用 fseek 函数来回移动指针 , 不容易确定当前指针位置 , 通过调用 ftell
函数确定指针位置 ;
二、使用 ftell 函数获取当前指针位置
代码示例 :
- 第一次打印指针位置 : 刚打开文件 , 还未读取数据 , 指针指向 0 位置 , 索引 0 ;
- 第二次打印指针位置 : 跳过了 4 字节数据 , 偏移了 4 字节 , 指针指向第 5 字节 , 索引 4 ;
- 第三次打印指针位置 : 跳过了 4 字节数据 , 又向后读取 2 字节 , 偏移了 6 字节 , 指向第七字节 , 索引 6 ;
#include <stdio.h>
int main()
// 以写文本的方式向文件中写出数据
FILE *p = fopen("D:/File/number.dat", "w");
// 写出 10 个字符
char array[10] = 1,2,3,4,5,6,7,8,9,10;
// 将 10 个字符写出到文件中
fwrite(array, 1, sizeof(array), p);
// 关闭文件
fclose(p);
// 跳过 4 字节读取文件 2 字节
FILE *p2 = fopen("D:/File/number.dat", "r");
// 使用 ftell 函数获取当前指针位置
int location = ftell(p2);
// 刚打开文件 , 还未读取数据 , 指针指向 0 位置 ★★★
printf("location = %d\\n", location);
// 读取数据缓冲区
char array2[2];
// 跳过 4 字节 , 此时当前位置是 0
fseek(p2, 4, SEEK_CUR);
// 使用 ftell 函数获取当前指针位置
location = ftell(p2);
// 跳过了 4 字节数据 , 偏移了 4 字节 ,
// 指针指向第 5 字节 , 索引 4 ★★★
printf("location = %d\\n", location);
// 读取 2 字节
fread(array2, 1, sizeof(array2), p2);
// 打印前 2 字节数据
printf("%d , %d\\n", array2[0], array2[1]);
// 使用 ftell 函数获取当前指针位置
location = ftell(p2);
// 跳过了 4 字节数据 , 又向后读取 2 字节 ,
// 偏移了 6 字节 , 指向第七字节 , 索引 6 ★★★
printf("location = %d\\n", location);
return 0;
执行结果 :
三、通过 ftell 计算文件大小
代码示例 : 打开文件后 , 直接使用 fseek 跳转到文件末尾 , 然后使用 ftell 获取当前指针 , 打印出指针位置 , 即可获取文件大小 ;
#include <stdio.h>
int main()
// 以写文本的方式向文件中写出数据
FILE *p = fopen("D:/File/number.dat", "w");
// 写出 10 个字符
char array[10] = 1,2,3,4,5,6,7,8,9,10;
// 将 10 个字符写出到文件中
fwrite(array, 1, sizeof(array), p);
// 关闭文件
fclose(p);
// 先打开文件
FILE *p2 = fopen("D:/File/number.dat", "r");
// 将文件指针移动到文件末尾
fseek(p2, 0, SEEK_END);
// 使用 ftell 函数获取当前指针位置
int location = ftell(p2);
// 通过读取当前文件指针位置, 即可获取文件大小 ★★★
printf("filesize = %d\\n", location);
// 将文件指针恢复
fseek(p2, 0, SEEK_SET);
// 使用 ftell 函数获取当前指针位置
location = ftell(p2);
// 查看指针是否恢复 ★★★
printf("location = %d\\n", location);
return 0;
执行结果 :
以上是关于C++通过文件指针获取文件大小的主要内容,如果未能解决你的问题,请参考以下文章
C++中怎样获取一个文件的大小,怎样判断一个文件是不是为空(文件存在,但是没有内容)