Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c

file

io

filesize

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

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}
like image 414
andrewrk Avatar asked Aug 11 '08 21:08

andrewrk


People also ask

How do I get the size of a file in C?

Using stat() function The stat() function takes the file path and returns a structure containing information about the file pointed by it. To get the size of the file in bytes, use the st_size field of the returned structure.

How do you find the file size?

Click the file or folder. Press Command + I on your keyboard. A window opens and shows the size of the file or folder.

Which function should you use to determine the size of a file *?

You can use stat (if you know the filename), or fstat (if you have the file descriptor).

Which of the following functions are used to determine size of a file in C?

ftell() in C This function is used to get the total size of file after moving the file pointer at the end of the file. It returns the current position in long type and file can have more than 32767 bytes of data.


4 Answers

On Unix-like systems, you can use POSIX system calls: stat on a path, or fstat on an already-open file descriptor (POSIX man page, Linux man page).
(Get a file descriptor from open(2), or fileno(FILE*) on a stdio stream).

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.

like image 125
Ted Percival Avatar answered Oct 16 '22 15:10

Ted Percival


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! :-)

like image 38
Orion Edwards Avatar answered Oct 16 '22 16:10

Orion Edwards


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.

like image 40
Derek Park Avatar answered Oct 16 '22 15:10

Derek Park


**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
}
like image 45
9 revs, 6 users 85% Avatar answered Oct 16 '22 16:10

9 revs, 6 users 85%