John
John

Reputation: 1119

How to get a file size even if it is already open for exclusive access?

The only way I found to get a file size is to use the GetFileSizeEx() function. However, this function requires a HANDLE to the file, and if the file is already open for exclusive access I will not be able to get a HANDLE for it and hence I will not be able to get its size.

So is there a way to get a file size even if it is already open for exclusive access?

Upvotes: 3

Views: 636

Answers (1)

Barmak Shemirani
Barmak Shemirani

Reputation: 31599

Edit, (see comments)
Using GetFileInformationByHandle

ULONGLONG filesize = 0; 
HANDLE h = CreateFile(filename, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 
    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
if (h != INVALID_HANDLE_VALUE)
{ 
    BY_HANDLE_FILE_INFORMATION info;
    memset(&info, 0, sizeof(BY_HANDLE_FILE_INFORMATION));
    if (GetFileInformationByHandle(h, &info)) 
    { 
        ULARGE_INTEGER ul = { 0 };
        ul.LowPart = info.nFileSizeLow; 
        ul.HighPart = info.nFileSizeHigh;
        filesize = ul.QuadPart; 
    } 
    CloseHandle(h); 
} 

Another method, see GetFileAttributesEx


There is also FindFirstFile, but this can be inaccurate

From MSDN documentation for FindFirstFile

Note In rare cases or on a heavily loaded system, file attribute information on NTFS file systems may not be current at the time this function is called. To be assured of getting the current NTFS file system file attributes, call the GetFileInformationByHandle function.

Using FindFirstFile

WIN32_FIND_DATA ffd;
HANDLE hfind = FindFirstFile(filename, &ffd);
if (hfind != INVALID_HANDLE_VALUE)
{
    DWORD filesize = ffd.nFileSizeLow;

    //for files larger than 4GB:
    ULARGE_INTEGER ul;
    ul.LowPart = ffd.nFileSizeLow;
    ul.HighPart = ffd.nFileSizeHigh;
    ULONGLONG llfilesize = ul.QuadPart;

    FindClose(hfind);
}

Upvotes: 3

Related Questions