引言

  有一天看见看到返回文件长度代码返回值都是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基础 如何得到文件长度的更多相关文章

  1. Java基础之读文件——使用通道读取混合数据1(ReadPrimesMixedData)

    控制台程序,本例读取Java基础之写文件部分(PrimesToFile2)写入的Primes.txt. 方法一:可以在第一个读操作中读取字符串的长度,然后再将字符串和二进制素数值读入到文本中.这种方式 ...

  2. ComicEnhancerPro 系列教程十八:JPG文件长度与质量

    作者:马健邮箱:stronghorse_mj@hotmail.com 主页:http://www.comicer.com/stronghorse/ 发布:2017.07.23 教程十八:JPG文件长度 ...

  3. Java基础之读文件——使用通道读取混合数据2(ReadPrimesMixedData2)

    控制台程序,本例读取Java基础之写文件部分(PrimesToFile2)写入的Primes.txt. 方法二:设置一个任意容量的.大小合适的字节缓冲区并且使用来自文件的字节进行填充.然后整理出缓冲区 ...

  4. Java基础之读文件——使用通道读二进制数据(ReadPrimes)

    控制台程序,本例读取Java基础之写文件部分(PrimesToFile)写入的primes.bin. import java.nio.file.*; import java.nio.*; import ...

  5. Java基础之读文件——从文件中读取文本(ReadAString)

    控制台程序,使用通道从缓冲区获取数据,读取Java基础之写文件(BufferStateTrace)写入的charData.txt import java.nio.file.*; import java ...

  6. Java基础之读文件——使用缓冲读取器读取文件(ReaderInputFromFile)

    控制台程序,本例读取Java基础之写文件部分(WriterOutputToFile)写入的Saying.txt. import java.io.*; import java.nio.file.*; i ...

  7. Java基础之读文件——使用输入流读取二进制文件(StreamInputFromFile)

    控制台程序,读取Java基础之读文件部分(StreamOutputToFile)写入的50个fibonacci数字. import java.nio.file.*; import java.nio.* ...

  8. UNIX,基础知识,文件IO,文件和目录

    2015.1.27星期二,早晨阴天,中午下雪了今天上午老师不上课,程序语句,记一下:main(void){ int c; while((c = getc(stdin)) != EOF) if(putc ...

  9. vc++基础班[21]---文件的基本操作之CFile

    ①.文件的创建.打开.关闭: 文件的创建.打开:CFile::Open 文件的关闭:CFile::Close   CFile::modeCreate:以新建方式打开,如果文件不存在,则新建:如果文件已 ...

随机推荐

  1. 【bzoj3886】[Usaco2015 Jan]Moovie Mooving 状态压缩dp+二分

    题目描述 Bessie is out at the movies. Being mischievous as always, she has decided to hide from Farmer J ...

  2. MySQL数据库引擎MyISAM与InnoDB的区别

    1. 存储结构 MyISAM:每个MyISAM在磁盘上存储成三个文件.第一个文件的名字以表的名字开始,扩展名指出文件类型..frm文件存储表定义.数据文件的扩展名为.MYD (MYData).索引文件 ...

  3. URL 编码规则

    规则: 1.将空格转换为加号(+) 2.对0-9.a-z.A-Z之间的字符保持不变 3.对于所有其他的字符,用这个字符的当前当前字符集编码在内存中的十六进制格式表示,并在每一个字节前加上一个百分号(% ...

  4. [NOIP2017]逛公园 最短路图 拓扑序DP

    ---题面--- 题解: 挺好的一道题. 首先我们将所有边反向,跑出n到每个点的最短路,然后f[i][j]表示从i号节点出发,路径长比最短路大j的方案数. 观察到,如果图中出现了0环,那么我们可以通过 ...

  5. JavaScript随机数生成方法

    实现随机数是各种编程语言都很常见的一个编程任务,下面介绍一下在JavaScript如何实现随机数.第一中方法通过重写Math.random方法实现,第二种方法改自一个C实现,都可以实现编程目的. 直接 ...

  6. eclipse中支持python

    1. 启动eclipse,help-> Install New Software; 2. 点击add 3. 设置Repository name: pydev Location: http://p ...

  7. CentOS 6.5 下安装配置 mysql

    如果要在Linux上做j2ee开发,首先得搭建好j2ee的开发环境,包括了jdk.tomcat.eclipse的安装(这个在之前的一篇随笔中已经有详细讲解了Linux学习之CentOS(七)--Cen ...

  8. 关于AVPlayerItem对象的属性duration返回播放总时长的坑

    最近在使用AVPlayer播放网络流媒体,发现一个坑: 就是playerItem.duration有可能不返回该网络多媒体资源的播放总时间长度,而是返回了一个奇怪的数据:nan, 因为我通过CMTim ...

  9. ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) A map B贪心 C思路前缀

    A. A Serial Killer time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  10. POJ_2112_Optimal Milking 这里有超级快的网络流板子

    Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among ...