How do you determine the size of a file in C?

How can I figure out the size of a file, in bytes?

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}

Answers


Based on NilObject's code:

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

off_t fsize(const char *filename) {
    struct stat st; 

    if (stat(filename, &st) == 0)
        return st.st_size;

    return -1; 
}

Changes:

  • Made the filename argument a const char.
  • Corrected the struct stat definition, which was missing the variable name.
  • Returns -1 on error instead of 0, which would be ambiguous for an empty file. off_t is a signed type so this is possible.

If you want fsize() to print a message on error, you can use this:

#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

off_t fsize(const char *filename) {
    struct stat st;

    if (stat(filename, &st) == 0)
        return st.st_size;

    fprintf(stderr, "Cannot determine size of %s: %s\n",
            filename, strerror(errno));

    return -1;
}

On 32-bit systems you should compile this with the option -D_FILE_OFFSET_BITS=64, otherwise off_t will only hold values up to 2 GB. See the "Using LFS" section of Large File Support in Linux for details.


Don't use int. Files over 2 gigabytes in size are common as dirt these days

Don't use unsigned int. Files over 4 gigabytes in size are common as some slightly-less-common dirt

IIRC the standard library defines off_t as an unsigned 64 bit integer, which is what everyone should be using. We can redefine that to be 128 bits in a few years when we start having 16 exabyte files hanging around.

If you're on windows, you should use GetFileSizeEx - it actually uses a signed 64 bit integer, so they'll start hitting problems with 8 exabyte files. Foolish Microsoft! :-)


Matt's solution should work, except that it's C++ instead of C, and the initial tell shouldn't be necessary.

unsigned long fsize(char* file)
{
    FILE * f = fopen(file, "r");
    fseek(f, 0, SEEK_END);
    unsigned long len = (unsigned long)ftell(f);
    fclose(f);
    return len;
}

Fixed your brace for you, too. ;)

Update: This isn't really the best solution. It's limited to 4GB files on Windows and it's likely slower than just using a platform-specific call like GetFileSizeEx or stat64.


**Don't do this (why?):

Quoting the C99 standard doc that i found online: "Setting the file position indicator to end-of-file, as with fseek(file, 0, SEEK_END), has undefined behavior for a binary stream (because of possible trailing null characters) or for any stream with state-dependent encoding that does not assuredly end in the initial shift state.**

Change the definition to int so that error messages can be transmitted, and then use fseek() and ftell() to determine the file size.

int fsize(char* file) {
  int size;
  FILE* fh;

  fh = fopen(file, "rb"); //binary mode
  if(fh != NULL){
    if( fseek(fh, 0, SEEK_END) ){
      fclose(fh);
      return -1;
    }

    size = ftell(fh);
    fclose(fh);
    return size;
  }

  return -1; //error
}

If you're fine with using the std c library:

#include <sys/stat.h>
off_t fsize(char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
    return 0;
}

POSIX

The POSIX standard has its own method to get file size. Include the sys/stat.h header to use the function.

Synopsis
  • Get file statistics using stat(3).
  • Obtain the st_size property.
Examples

Note: It limits the size to 4GB. If not Fat32 filesystem then use the 64bit version!

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

int main(int argc, char** argv)
{
    struct stat info;
    stat(argv[1], &info);

    // 'st' is an acronym of 'stat'
    printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char** argv)
{
    struct stat64 info;
    stat64(argv[1], &info);

    // 'st' is an acronym of 'stat'
    printf("%s: size=%ld\n", argv[1], info.st_size);
}

ANSI C (standard)

The ANSI C doesn't directly provides the way to determine the length of the file. We'll have to use our mind. For now, we'll use the seek approach!

Synopsis
  • Seek the file to the end using fseek(3).
  • Get the current position using ftell(3).
Example
#include <stdio.h>

int main(int argc, char** argv)
{
    FILE* fp = fopen(argv[1]);
    int f_size;

    fseek(fp, 0, SEEK_END);
    f_size = ftell(fp);
    rewind(fp); // to back to start again

    printf("%s: size=%ld", (unsigned long)f_size);
}

If the file is stdin or a pipe. POSIX, ANSI C won't work. It will going return 0 if the file is a pipe or stdin.

Opinion: You should use POSIX standard instead. Because, it has 64bit support.


And if you're building a Windows app, use the GetFileSizeEx API as CRT file I/O is messy, especially for determining file length, due to peculiarities in file representations on different systems ;)


A quick search in Google found a method using fseek and ftell and a thread with this question with answers that it can't be done in just C in another way.

You could use a portability library like NSPR (the library that powers Firefox) or check its implementation (rather hairy).


I used this set of code to find the file length.

//opens a file with a file descriptor
FILE * i_file;
i_file = fopen(source, "r");

//gets a long from the file descriptor for fstat
long f_d = fileno(i_file);
struct stat buffer;
fstat(f_d, &buffer);

//stores file size
long file_length = buffer.st_size;
fclose(i_file);

Try this --

fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);

What this does is first, seek to the end of the file; then, report where the file pointer is. Lastly (this is optional) it rewinds back to the beginning of the file. Note that fp should be a binary stream.

file_size contains the number of bytes the file contains. Note that since (according to climits.h) the unsigned long type is limited to 4294967295 bytes (4 gigabytes) you'll need to find a different variable type if you're likely to deal with files larger than that.


Here's a simple and clean function that returns the file size.

long get_file_size(char *path)
{
    FILE *fp;
    long size = -1;
    /* Open file for reading */
    fp = fopen(path, "r");
    fseek(fp, 0, SEEK_END);
    size = ftell(fp); 
    fp.close();
    return 
}

You're going to need to use a library function to retrieve the details of a file. As C is completely platform independent, you're going to need to let us know what platform / operating system you're developing for!


Looking at the question, ftell can easily get the number of bytes.

  long size ;
  size = ftell(FILENAME);
  printf("total size is %ld bytes",size);

You can open the file, go to 0 offset relative from the bottom of the file with

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

the value returned from fseek is the size of the file.

I didn't code in C for a long time, but I think it should work.


Need Your Help

How to test Cordova/ionic app on iOS device?

ios iphone xcode cordova ionic-framework

I'm building an app which now runs fine in the iOS emulator, so I now want to test the app on an iOS device. I registered with the Apple Developer Program and ran ionic run ios, which ended with the

Is the documentation for gluProject missing perspective division?

c++ opengl glu projection-matrix

The OpenGL documentation for gluProject writes that the projection of point v is computed using the given projection and model-view matrix via v'' = P * M * v then window coordinates are derived us...