stat64 一个大(~5GB)文件

stat64 a large (~5GB) file

在 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 从 ld 更改为 llu

#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.

感谢大家!

  1. 启用所有编译器警告 - 它们比在 Stack overflow 上发布问题更快。

  2. 当打印像 myst.st_size 这样的整数类型时,它是 off_t 类型,缺少匹配的 printf 说明符,考虑简单地转换为最宽的类型和使用其匹配的 printf 说明符。

    // printf("%s size: %ld\n", filename, myst.st_size);
    printf("%s size: %jd\n", filename, (intmax_t) myst.st_size);
    

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

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

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