程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C基礎 如何得到文件長度,C基礎文件長度

C基礎 如何得到文件長度,C基礎文件長度

編輯:關於C語言

C基礎 如何得到文件長度,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\n", 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\n", 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\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 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更適合的了, 更快速輕巧的了.  一切都是抉擇, 沒有最好, 只有最合適.

 

後記

  錯誤是難免的, 歡迎交流提高.  也許我們年少的時候幻想著成為大英雄, 最終也只是拿著血汗錢成了房奴.

  

有夢想的人是令人羨慕的, 有夢想的人是令人惋惜的.  愛我所愛, 開心就好 ~~~~~~~~~

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved