C基础 如何得到文件长度
引言
有一天看见看到返回文件长度代码返回值都是long,就感觉怪怪的, 一般32位long最大也就2G.
而大文件太多了, 一个Dota2安装包估计都得10多G吧. 一般C得到文件长度代码
/*
* 得到文件长度, 一种通用老的写法
* path : 文件路径
* : 返回文件长度
*/
long
file_getsize(const char * path) {
FILE * txt;
long rt; if ((!path) || !(txt = fopen(path, "rb")))
return ; fseek(txt, , SEEK_END);
rt = ftell(txt); fclose(txt);
return rt;
}
如上套路, 比较耿直的. 写个测试代码
#include <stdio.h> /*
* 得到文件长度, 一种通用老的写法
* path : 文件路径
* : 返回文件长度
*/
long file_getsize(const char * path); int main(int argc, char * argv[]) {
const char * path;
int i = ; while (i < argc) {
path = argv[i];
printf("%s => %ld\n", path, file_getsize(path));
++i;
} return ;
}
执行正常的测试结果看下图

扯一点, 对于 fopen "rb"后面b表示采用二进制流方式处理, 默认是t文本模式. 前者速度快一点, 后者做了一些特殊处理.
主要是不同系统对换行符处理不同业务诞生的. 推荐用 b 二进制处理方式更快些.(21世纪是个装b的年代, 全是BBB)
前言
这里我们再做一个实验 , 看下面大文件 . 继续用上面代码测试一下. 先看测试文件

测试结果如下

这时候我们需要用新的文件操作代码,想办法了. 其实上面ftell方式得到代码, 来回移动文件指针性能很低.
因为文件大小操作系统知道, 直接问它要是最快的. 先在window 上写一段代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <inttypes.h> /*
* 得到文件长度, windows 品台用法
* path : 文件路径
* : 返回文件长度
*/
int64_t file_getsize(const char * path); int main(int argc, char * argv[]) {
const char * path;
int i = ; while (i < argc) {
path = argv[i];
printf("%s => %ld\n", path, file_getsize(path));
++i;
} return ;
} /*
* 得到文件长度, windows 上适用方法
* path : 文件路径
* : 返回文件长度
*/
int64_t
file_getsize(const char * path) {
struct _stat64 info = { }; if (!path || !*path)
return ; _stat64(path, &info);
return info.st_size;
}
上面就是完整的测试代码, 主要通过 sys/stat.h 下面_stat64 函数得到 8字节长度的文件大小表示.
我们也继续测试一下. 结果很满意

到这里我们. 在window上测试完毕.
正文
我们在linux上测试一下. 先看代码我写好的代码 main_linux.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <inttypes.h> /*
* 得到文件长度, linuxs 平台用法
* path : 文件路径
* : 返回文件长度
*/
int64_t file_getsize(const char * path); int main(int argc, char * argv[]) {
const char * path;
int i = ; // 测试demo
struct stat info;
printf("info.st_size size = %ld\n", sizeof(info.st_size));
printf("unsigned long size = %ld\n", sizeof(unsigned long)); while (i < argc) {
path = argv[i];
printf("%s => %ld\n", path, file_getsize(path));
++i;
} return ;
} /*
* 得到文件长度, linux 上适用方法
* path : 文件路径
* : 返回文件长度
*/
int64_t
file_getsize(const char * path) {
struct stat info = { }; if (!path || !*path)
return ; stat(path, &info);
return info.st_size;
}
编译命令
gcc -Wall -ggdb2 -o main_linux.out main_linux.c
后面查看 sys/stat.c 源码

有兴趣可以看看, 得到的结论是, linux会根据平台自动帮我们确定是 stat64 还是 stat. 我用的是64位的, 默认stat也是stat64.
返回的long 是 8字节. 可以看下面结果

这里也解决了一个问题, 一般 off_t 结构是8字节的unsigned long 结构. window是long long结构. 不同平台实现不一样.
如果希望这个函数是跨平台的 那么 需要在 window 上做
#if defined(_MSC_VER)
# define stat _stat64
#endif
是不是很简单. 就能够让我们的得到文件长度代码跨平台了. 哎, 这种语言, 细节太多, 不利于生产. 大师们也老了, 改进的机会也少了, 太稳定了.
如果只为了快速的性能那么没有谁比C更适合的了, 更快速轻巧的了. 一切都是抉择, 没有最好, 只有最合适.
后记
错误是难免的, 欢迎交流提高. 也许我们年少的时候幻想着成为大英雄, 最终也只是拿着血汗钱成了房奴.

有梦想的人是令人羡慕的, 有梦想的人是令人惋惜的. 爱我所爱, 开心就好 ~~~~~~~~~
C基础 如何得到文件长度的更多相关文章
- Java基础之读文件——使用通道读取混合数据1(ReadPrimesMixedData)
控制台程序,本例读取Java基础之写文件部分(PrimesToFile2)写入的Primes.txt. 方法一:可以在第一个读操作中读取字符串的长度,然后再将字符串和二进制素数值读入到文本中.这种方式 ...
- ComicEnhancerPro 系列教程十八:JPG文件长度与质量
作者:马健邮箱:stronghorse_mj@hotmail.com 主页:http://www.comicer.com/stronghorse/ 发布:2017.07.23 教程十八:JPG文件长度 ...
- Java基础之读文件——使用通道读取混合数据2(ReadPrimesMixedData2)
控制台程序,本例读取Java基础之写文件部分(PrimesToFile2)写入的Primes.txt. 方法二:设置一个任意容量的.大小合适的字节缓冲区并且使用来自文件的字节进行填充.然后整理出缓冲区 ...
- Java基础之读文件——使用通道读二进制数据(ReadPrimes)
控制台程序,本例读取Java基础之写文件部分(PrimesToFile)写入的primes.bin. import java.nio.file.*; import java.nio.*; import ...
- Java基础之读文件——从文件中读取文本(ReadAString)
控制台程序,使用通道从缓冲区获取数据,读取Java基础之写文件(BufferStateTrace)写入的charData.txt import java.nio.file.*; import java ...
- Java基础之读文件——使用缓冲读取器读取文件(ReaderInputFromFile)
控制台程序,本例读取Java基础之写文件部分(WriterOutputToFile)写入的Saying.txt. import java.io.*; import java.nio.file.*; i ...
- Java基础之读文件——使用输入流读取二进制文件(StreamInputFromFile)
控制台程序,读取Java基础之读文件部分(StreamOutputToFile)写入的50个fibonacci数字. import java.nio.file.*; import java.nio.* ...
- UNIX,基础知识,文件IO,文件和目录
2015.1.27星期二,早晨阴天,中午下雪了今天上午老师不上课,程序语句,记一下:main(void){ int c; while((c = getc(stdin)) != EOF) if(putc ...
- vc++基础班[21]---文件的基本操作之CFile
①.文件的创建.打开.关闭: 文件的创建.打开:CFile::Open 文件的关闭:CFile::Close CFile::modeCreate:以新建方式打开,如果文件不存在,则新建:如果文件已 ...
随机推荐
- Java的第一个程序-Hello, World !
学了一个月的Java,现在总结一下,就算复习了. 一.安装Java环境 这个没啥好说的. 1. 官网下载JDK安装 2. 配置环境变量.注意的是:环境变量配置好以后,如果cmd中运行 java 命令没 ...
- [BZOJ4822] [CQOI2017] 老C的任务
题目链接 BZOJ:https://lydsy.com/JudgeOnline/problem.php?id=4822. 洛谷:https://www.luogu.org/problemnew/sho ...
- [洛谷P3346][ZJOI2015]诸神眷顾的幻想乡
题目大意:给你一棵$n$个点的树,最多有$20$个叶子节点,问共有几个不同的子串 题解:广义$SAM$,对每个叶子节点深搜一次,每个节点的$lst$设为这个节点当时的父亲,这样就可以时建出来的$SAM ...
- 洛谷 P1363 幻想迷宫 解题报告
P1363 幻想迷宫 题目描述 背景 Background (喵星人LHX和WD同心协力击退了汪星人的入侵,不幸的是,汪星人撤退之前给它们制造了一片幻象迷宫.) WD:呜呜,肿么办啊-- LHX:mo ...
- js空对象判断 isPlainObject
//有缺陷,JSON.stringify(obj)中,如果obj本来是空的,又继承了一个非空的对象那么结果也会是“{}” 1. JSON.stringify(obj) == '{}' 2. Objec ...
- bzoj2058: [Usaco2010 Nov]Cow Photographs(逆序对)
题目大意:给出n个数的序列,每次可以交换相邻的两个数,问把序列变成编号i在编号i+1左边,编号1在编号n右边(一个环)最少需要多少步.如:35421最少交换两次变为34512. 一开始看到这题,只会O ...
- IDEA的使用总结篇-1
随笔:随着回首所在的公司的日益扩大,所在的技术中心也日渐兵强马壮,但由于各位新老同仁的开发工具一直未曾统一,所以小编的老大终于一声令下,统一开发工具!统一使用IDEA,而且每个人今天要交一份IDEA的 ...
- 使用rsyslog编程,产生trace信息,记录到日志中
参考:http://blog.csdn.net/nowayings/article/details/38926501 https://www.cnblogs.com/bonelee/p/6234647 ...
- Django Session配置
Django Session的三种存储方式 SESSION_ENGINE='django.contrib.sessions.backends.db' # default 保存到数据库中,依赖 'dja ...
- BZOJ1878: [SDOI2009]HH的项链 (离线查询+树状数组)
1878: [SDOI2009]HH的项链 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1878 Description: HH有一串由 ...