I have reduced the problem to the following basic function which should simply print the number of bytes in the file.
When I execute it for a file of 83886080 bytes (80 MB) it prints the correct number. However for a file of 4815060992 bytes (4.48 GB) it prints 520093696 which is way to low.
It seems to have something to do with the SEEK_END option because if I set the pointer to 4815060992 bytes manually (e.g. _fseeki64(fp, (__int64)4815060992, SEEK_SET)
_ftelli64
does return the correct position.
So a workaround would be to get the proper file size without using SEEK_END, how is this done?
The code is compiled on a 32 bit Windows system (hence __int64
, _iseeki64
and _ftelli64
) with MinGW.
In short: what am I doing wrong here?
void printbytes(char* filename)
{
FILE *fp;
__int64 n;
int result;
/* Open file */
fp = fopen(filename, "rb");
if (fp == NULL)
{
perror("Error: could not open file!\n");
return -1;
}
/* Find end of file */
result = _fseeki64(fp, (__int64)0, SEEK_END);
if (result)
{
perror("Error: fseek failed!\n");
return result;
}
/* Get number of bytes */
n = _ftelli64(fp);
printf("%I64d\n", n);
/* Close file */
fclose(fp);
}
In Windows, you should be able to "go native" and just use
GetFileSizeEx()
.I would also advise you to read the generated code to see if it maybe is some 64-bit confusion that prevents your stdio-based code from working.
sorry for not posting sooner but I have been preoccupied with other projects for a while. The following solution works:
The trick was using
_open
instead offopen
to open the file. I still don't understand exactly why this has to be done, but at least this works now. Thanks to everyone for your suggestions which eventually pointed me in the right direction. (this is a copy of the answer to related question number 4003405).