首页 > 解决方案 > stat64 一个大(~5GB)文件

问题描述

在 raspbian 上,我正在尝试做stat/stat64一个大文件:5.4G /tmp/some.mpg. 这是代码:

#include <stdio.h>
#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#include <sys/stat.h>

int main(){
    char filename[] = "/tmp/some.mpg";
    struct stat64 myst;
    int x = stat64(filename, &myst );
    if ( x < 0 ){
        printf("x is %d\n", x);
        perror("stat failure");
    }
    printf("%s size: %ld\n", filename, myst.st_size);

    return 0;
}

但是,当我运行它时它会显示错误的信息:

$ gcc bigsize.c -D_FILE_OFFSET_BITS=64  -o bigsize
$ ./bigsize 
/tmp/some.mpg size: 1435916040
$ ls -ltr /tmp/some.mpg 
-rw-r--r-- 1 XXX YYYY 5730883336 Jul 27 08:44 /tmp/some.mpg

x86_64这似乎工作正常,而不是armv7l

请告诉我完成此操作的正确方法,谢谢!

更新 1

这似乎有效,将 printf 从更改ldllu

#include <stdio.h>
#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#include <sys/stat.h>

int main(){
        char filename[] = "/tmp/some.mpg";
        struct stat64 myst;
        int x = stat64(filename, &myst );
        if ( x < 0 ){
                printf("x is %d\n", x);
                perror("stat failure");
        }
        printf("%s size: %llu\n", filename, myst.st_size);

        return 0;
}

更新 2

这有效,在阅读答案后:

#include <stdio.h>
#include <inttypes.h>

#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#include <sys/stat.h>

int main(){
    char filename[] = "/tmp/some.mpg";
    struct stat64 myst;
    int x = stat64(filename, &myst );
    if ( x < 0 ){
        printf("x is %d\n", x);
        perror("stat failure");
    }
    printf("%s size: %llu\n", filename, myst.st_size);
    printf("%s size: %jd\n", filename, (intmax_t)myst.st_size);
    printf("file %s is %" PRIdMAX " bytes.\n", filename, (intmax_t)myst.st_size);

    return 0;
}

这样编译:

$ gcc bigsize.c  -o bigsize -Wall -Wextra ; echo $?
0

跑:

 $ ./bigsize 
/tmp/some.mpg size: 5730883336
/tmp/some.mpg size: 5730883336
file /tmp/some.mpg is 5730883336 bytes.

谢谢大家!

标签: craspbianstat

解决方案


问题是你告诉printf()它你给它的参数是 a long,但实际上传递给它一个参数,在这种情况下是 a long long,当两种类型的大小不同时会导致未定义的行为。它适用于 x86_64 系统,因为longlong long都是 64 位的,但我敢打赌 arm 系统使用 32 位long和 64 位long long

当您不知道要打印的确切类型时,一种可移植的方法是将其转换为可能的最大类型(intmax_tfrom <stdint.h>,并使用打印宏 from<inttypes.h>来显示它:

printf("file %s is %" PRIdMAX " bytes.\n", filename, (intmax_t)myst.st_size);

推荐阅读