views:

331

answers:

5

Hi!

I made a simple function, which get's a file's size.

int file_size( char * filename )
{
     int size;
     struct stat st;

     stat( filename, &st );
     size = st.st_size;

     return size;

}//file_size

It is working fine, but if i have a file which size is bigger than 4Gb than i get a negativ number back, and of course this isn't the correct file size. So how can i get such a big file's size? I think, that the return value should anything else like int but i don't know what, and i don't think, that would solve my problem.

Thanks,

kampi

Update:

Hi!

I found the solution. I have to use __stat64. I modifyed my function, and now it is retrieving the real size. I tested it with an 8Gb big file.

unsigned long long int file_size( char * filename )
{
    unsigned long long int size;
    struct __stat64 st;

    __stat64( filename, &st );
    size = st.st_size;

   return size;

}//file_size

And a notice:

When i used printf, i had to use "%I64d" to print it out.

+4  A: 

You can use the Win32 GetFileSizeEx function.

HANDLE aFile = CreateFile
(
  filename,
  FILE_READ_ATTRIBUTES,
  0,
  NULL,
  OPEN_EXISTING,
  FILE_ATTRIBUTE_NORMAL,
  NULL
);

if (aFile != INVALID_HANDLE_VALUE)
{
  long long aSize;
  GetFileSizeEx(aFile, &aSize);

  CloseHandle(aFile);
  return aSize;
}
else
  return -1;
Kerido
The only caveat with this might be (not very sure) that it might be difficult to mix and match posix calls with win32 calls within the same process. It looks like the OP might be coming in from a unix background and wanting to use posix calls only.
Moron
A: 

I think , problem is because of file size more than INT_MAX , So that it is giving you negative values .

Probably you can do type cast for long data type , it may work.

Otherwise use , fseek , ftell function . then subtract end file pointer from start file pointer . It will also give you file size. ( number of bytes ) .

pavun_cool
+2  A: 

You can probably use _stat64.

Moron
Thank you very much, this was the easiest way, to solve my problem.
kampi
+1  A: 

st_size is defined as long in wchar.h, so you could probably try with long, instead of int

struct stat {
    ....
    _off_t     st_size;
    ....
}

....

typedef long _off_t;  

May be like this

long file_size( char * filename )
{
     long size;
     struct stat st;

     stat( filename, &st );
     size = st.st_size;

     return size;

}//file_size
S.Mark
No reason you can't prepend "unsigned" either as file size is unlikely to be negative.
Ninefingers
If the truncation happens in st.st_size, I am curious how assigning it to a long helps in this situation.
ArunSaha
+2  A: 

In such cases, return value of stat() might be -1, and errno set to EOVERFLOW.

The man page for stat on my (64 bit x86 machine) says:

EOVERFLOW

(stat()) path refers to a file whose size cannot be represented in the type off_t. This can occur when an application compiled on a 32-bit platform without -D_FILE_OFFSET_BITS=64 calls stat() on a file whose size exceeds (2<<31)-1 bits.

ArunSaha