I need to determine the file size in bytes of binary regular files under POSIX. I'm aware of how to use this with lseek() and fstat():
#include <sys/stat.h> // for open() and fstat()
#include <fcntl.h> // for O_RDONLY
#include <unistd.h> // for lseek()
int fd = open("something.bin", O_RDONLY);
if (fd == -1)
{
perror("Unable to open file to read");
return EXIT_FAILURE;
}
// Using lseek()
const off_t size = lseek(fd, 0, SEEK_END);
if (size == (off_t) -1)
{
perror("Unable to determine input file size");
return EXIT_FAILURE;
}
// Don't forget to rewind
if (lseek(fd, 0, SEEK_SET) != 0)
{
perror("Unable to seek to beginning of input file");
return EXIT_FAILURE;
}
...
// Using fstat()
struct stat file_stat;
int rc = fstat(fd, &file_stat);
if (rc != 0 || S_ISREG(file_stat.st_mod) == 0)
{
perror("fstat failed or file is not a regular file");
return EXIT_FAILURE;
}
const off_t size = file_stat.st_size;
Why would I prefer one solution over the other?
Does one approach do more (and perhaps unnecessary) than the other?
Are there other POSIX compliant or standard C solutions that should be preferred?
Normally stat(), fstat() will read the metadata of the file to retrieve the file properties for the user. Mechanism to store metadata of files may vary from file system to file system but in general designed to give optimum speed/time complexity.
'file size' is one of the file properties stored in metadata and is updated at various file operations (e.g. write/append etc). Further fstat() doesn't require you to 'open()' the file.
On the other hand, Every 'open()' and 'lseek()' operations together could involve disk activity if the file is not present in the page cache of the operating system and could be exponentially more expensive.
Therefore I would recommend fstat().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With