Sep 182013
 

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.

  1. Using GetFileSizeEx
  2. Using _wstat64
  3. Using GetFileInformationByHandleEx
  4. Using FindFirstFileW
  5. 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;
}

  One Response to “[Windows API] Code to get file size”

  1. […] [Windows API] Code to get file size » bits and bytes […]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.