zoukankan      html  css  js  c++  java
  • 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 0;
    
        fseek(txt, 0, 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 = 1;
    
        while (i < argc) {
            path = argv[i];
            printf("%s => %ld
    ", path, file_getsize(path));
            ++i;
        }
    
        return 0;
    }
    

    执行正常的测试结果看下图

    扯一点, 对于 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 = 1;
    
        while (i < argc) {
            path = argv[i];
            printf("%s => %ld
    ", path, file_getsize(path));
            ++i;
        }
    
        return 0;
    }
    
    /*
     * 得到文件长度, windows 上适用方法
     * path        : 文件路径
     *            : 返回文件长度
     */
    int64_t
    file_getsize(const char * path) {
        struct _stat64 info = { 0 };
    
        if (!path || !*path)
            return 0;
    
        _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 = 1;
    
        // 测试demo
        struct stat info;
        printf("info.st_size size = %ld
    ", sizeof(info.st_size));
        printf("unsigned long size = %ld
    ", sizeof(unsigned long));
    
        while (i < argc) {
            path = argv[i];
            printf("%s => %ld
    ", path, file_getsize(path));
            ++i;
        }
    
        return 0;
    }
    
    /*
     * 得到文件长度, linux 上适用方法
     * path        : 文件路径
     *            : 返回文件长度
     */
    int64_t
    file_getsize(const char * path) {
        struct stat info = { 0 };
    
        if (!path || !*path)
            return 0;
    
        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更适合的了, 更快速轻巧的了.  一切都是抉择, 没有最好, 只有最合适.

    后记

      错误是难免的, 欢迎交流提高.  也许我们年少的时候幻想着成为大英雄, 最终也只是拿着血汗钱成了房奴.

      

    有梦想的人是令人羡慕的, 有梦想的人是令人惋惜的.  爱我所爱, 开心就好 ~~~~~~~~~

      

  • 相关阅读:
    意法半导体STM32MP157A MPU加持,米尔科技首款ST Linux开发板MYD-YA157C评测
    基于nxp i.mx8m mini的新一代高性价比核心板之王
    Spring IoC容器-ApplicationContext
    XML文档
    Spring资源访问
    Spring框架简介
    SpringBoot整合RabbitMQ
    发布订阅模式
    主题模式
    RabbitMQ Work Queues(工作队列)
  • 原文地址:https://www.cnblogs.com/life2refuel/p/5679285.html
Copyright © 2011-2022 走看看