In this blog post I’ll be demonstrating different API’s and techniques used to retrieve size of a file. I haven’t tested this much, you might want to add parameter integrity check etc., also probably better error checks. Use this code at your own risk.
- Using GetFileSizeEx
- Using _wstat64
- Using GetFileInformationByHandleEx
- Using FindFirstFileW
- Using fseek and ftell
Method 1: Using GetFileSizeEx
Here is a short code snippet to get size of a file using the Windows API GetFileSizeEx. Wrote this for a friend, so thought this will be useful for others as well.
Windows Store apps: GetFileSizeEx is not supported. Use GetFileInformationByHandleEx.
__int64 PrvGetFileSize(const wchar_t* path)
{
HANDLE hFile = ::CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("Failed to open file: %S, error: %lu", path, GetLastError());
return -1;
}
LARGE_INTEGER li = { 0 };
if(GetFileSizeEx(hFile, &li) == 0)
{
printf("Failed to get file size: %lu", GetLastError());
CloseHandle(hFile);
return -1;
}
CloseHandle(hFile);
return li.QuadPart;
}
Method 2: Using _wstat64
__int64 PrvStat64(const wchar_t* path)
{
struct _stat64 flstat = {0};
const int rv = _wstat64( path, &flstat );
// Check if _stat64 call worked
if( rv != 0 )
{
perror( "Problem getting information" );
switch (errno)
{
case ENOENT:
printf("File %S not found.\n", path);
return -1;
case EINVAL:
printf("Invalid parameter to _stat.\n");
return -1;
default:
/* Should never be reached. */
printf("Unexpected error in _stat.\n");
return -1;
}// End switch
}// End if
return flstat.st_size;
}
Method 3: Using GetFileInformationByHandleEx
__int64 PrvGetFileInformationByHandleEx(const wchar_t* path)
{
HANDLE hFile = ::CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("Failed to open file: %S, error: %lu", path, GetLastError());
return -1;
}
FILE_STANDARD_INFO finfo = {0};
if(GetFileInformationByHandleEx (hFile, FileStandardInfo, &finfo, sizeof(finfo)) == 0)
{
printf("Failed to get file size: %lu", GetLastError());
CloseHandle(hFile);
return -1;
}
CloseHandle(hFile);
return finfo.EndOfFile.QuadPart;
}
Method 4: Using FindFirstFile
__int64 PrvFindFirstFile(const wchar_t* path)
{
WIN32_FIND_DATAW fdata = {0};
HANDLE hFind = FindFirstFileW(path, &fdata);
if (hFind == INVALID_HANDLE_VALUE)
{
printf ("FindFirstFile failed (%d)\n", GetLastError());
return -1;
}
ULONGLONG Size = fdata.nFileSizeLow;
Size |= (((__int64)fdata.nFileSizeHigh) << 32);
FindClose(hFind);
return Size;
}
Method 5: Using a combination of fseek and ftell
__int64 PrvSeekFTell(const wchar_t* path)
{
FILE* file = NULL;
errno_t err = _wfopen_s(&file, path, L"r");
if(err)
{
printf("Error: Could not open file: %s", path);
return -1;
}
_fseeki64(file, 0, SEEK_SET); // Goto beginning
_fseeki64(file, 0, SEEK_END); // Goto end
const __int64 size = _ftelli64(file); // Tell position, i.e. size
fclose(file);
return size;
}