how to get size of file bigger than LONG_MAX in c?

86 Views Asked by At

how do you get the size of a file bigger than LONG_MAX in C?

I know you can use fopen+SEEK_END+ftell as long as your filesize don't exceed LONG_MAX, but what if it does?

#include <stdio.h>
int main(int argc, char **argv) {
    FILE *fp;
    fp = fopen(argv[0], "rb");
    fseek(fp, 0, SEEK_END);
    long fsize = ftell(fp);
    fclose(fp);
    printf("%ld\n", fsize);
}

in C++ i would use std::filesystem::file_size() returning std::uintmax_t

2

There are 2 best solutions below

1
gulpr On

The comment suggests windows.

You have plenty of functions in Windows:

  • _fstat, _fstat32, _fstat64, _fstati64, _fstat32i64, _fstat64i32
  • GetFileSizeEx
  • ftell, _ftelli64

Unfortunately you need to use #ifs to compile your programs for windows and Linux.

1
dbush On

Putting aside the file size issue, using ftell to seek to the end of a file isn't a good way to do so as it incurs extra I/O (at least on a traditional disk drive, not sure about SSD) to do so.

A file's size is included as part of its directory entry, so it's best to get it directly from there. On UNIX-like systems, you would use the stat call, while on Windows you could call _stat (32-bit file size) or _stat64 (64-bit file size). These also don't require that the file be opened.

These corresponding functions and types are close enough that you can use #if directives to set up a common type you can use in either case.

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>

// defined by MSVC
#ifdef _MSC_VER

typedef struct _stat64 stat_struct;
#define stat_func(name, buf) _stat64(name, buf)

#else

#include <unistd.h>

typedef struct stat stat_struct;
#define stat_func(name, buf) stat(name, buf)

#endif

int main(int argc, char **argv) 
{
    stat_struct stat;
    stat_func(argv[1], &stat);
    printf("%lld\n", stat.st_size);
}