How can I figure out the size of a file, in bytes?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
How can I figure out the size of a file, in bytes?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
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!
as long as you have "iostream" available, you can do the following:
unsigned int fsize(char* file){ long begin,end; ifstream myfile (file); begin = myfile.tellg(); myfile.seekg (0, ios::end); end = myfile.tellg(); return end-begin; }
is the idea. My C++ chops are a little creaky, so pushing a char* to an ifstream might not work as I wrote it... a good look at tellg() and seekg() will help you get the details.
If you're fine with using the std c library:
#include <sys/stat.h>
off_t fsize(char *file) {
struct stat;
if (stat(file, &stat) == 0) {
return stat.st_size;
}
return 0;
}
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.
Matt's solution should work, except that it's C++ instead of C, and the initial tell shouldn't be necessary.
unsigned int fsize(char* file
{
FILE * f = fopen(file, "r");
fseek(f, 0, SEEK_END);
return (unsigned int)ftell(f);
}
Fixed your brace for you, too. ;)
Don't do this (why?):
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
}
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).
@NilObject That's not standard C. It's part of the POSIX standard, but not the C standard.
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! :-)
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 ;)
Based on NilObject's code:
#include <sys/stat.h>
off_t fsize(const char *filename) {
struct stat st;
if (stat(filename, &st) == 0)
return st.st_size;
return -1;
}
Changes:
const char
.struct stat
definition, which was missing the variable name.-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 <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.