File operation

I am doing a win32 application,in that iam opening a file & based on the sizeof that file i have to allocate memory dynamically.what function call i have to use.I tryed like this but itsnot working.File is opening correctly and getting value for the function GetFileSizeEx().Please correct me
1
2
3
4
5
6
7
8
9
10
11
12
FILE *FH;
char cFileName[]="abc.txt";
LARGE_INTEGER filesize;
errno_t err=fopen_s(&FH,cFileName,"r");
if(err)
return false;
if(FH!=INVALID_HANDLE_VAUE)
{
BOOL b=GetFileSizeEx(FH,&filesize)
TCHAR *pStore=new TCHAR[filesize.u.LowPart]

}
Last edited on
You cannot open file with fopen and use that handle for GetFileSizeEx. Use CreateFile function instead

1
2
3
4
5
6
7
8
9
10
11
12
char cFileName[]="abc.txt";
LARGE_INTEGER filesize;

HANDLE FH=CreateFile(cFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);


if(FH!=INVALID_HANDLE_VAUE)
{
BOOL b=GetFileSizeEx(FH,&filesize)
TCHAR *pStore=new TCHAR[filesize.u.LowPart]
}
}


http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
Last edited on
See #3 for the best answer.

Also, rather than using

TCHAR *pStore=new TCHAR[filesize.u.LowPart];

you should use

vector<TCHAR> store(filesize.LowPart); // no need for the .u

and then use, as you no doubt know, &store[0] when you want to pass the vector to a C-style function which takes a TCHAR*.

Andy

#1 -- _fileno + _get_osfhandle

It is possible to get the underlying Win32 file handle from a FILE* (as returned by fopen_s and fopen) using _fileno + _get_osfhandle. For example:

(This trick is only really of use when you need to use Win32 File API function from legacy code otherwise written using POSIX-style calls.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#define WIN32_LEAN_AND_MEAN
#include <windows.h> // for GetFileSize, DWORD
#include <iostream>
#include <cstdio>
#include <io.h> // for _get_osfhandle
using namespace std;

void displayFileSize(const char *cFileName)
{
    FILE *FH=NULL;
    errno_t err=fopen_s(&FH,cFileName,"r");
    if(err)
    {
        cout << "fopen_s failed" << endl;
        return;
    }
    HANDLE hFile=(HANDLE)_get_osfhandle(_fileno(FH));
    if(hFile != INVALID_HANDLE_VALUE)
    {
        LARGE_INTEGER filesize = {0};
        BOOL b=GetFileSizeEx(hFile,&filesize);
        if(b)
            cout << "GetFileSizeEx returned : " << filesize.QuadPart << endl;
        else
            cout << "GetFileSizeEx failed" << endl;
    }
    fclose(FH);
}

int main()
{
    char cFileName[]="abc.txt";
    displayFileSize(cFileName);

    return 0;
}


#2 -- fseek + ftell

To get the file size, you can avoid Win32 calls completely; the usual way to get the file size is to use fseek and ftell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstdio>
using namespace std;

#pragma comment(lib, "Lz32.lib")

void displayFileSize(const char *cFileName)
{
    FILE *FH=NULL;
    errno_t err=fopen_s(&FH,cFileName,"r");
    if(err)
    {
        cout << "fopen_s failed" << endl;
        return;
    }
    // there are also the non-standard _fseeki64 and _ftelli64
    // if you need to deal with LARGE files
    if( fseek(FH, 0L, SEEK_END) == 0 )
    {
        long filesize = ftell(FH);
        if(filesize == -1)
            cout << "ftell failed" << endl;
        else
            cout << "ftell returned : " << filesize << endl;
        fseek(FH, 0L, SEEK_SET); // to be tidy
    }
    else
    {
        cout << "fseek failed" << endl;
    }

    fclose(FH);
}

int main()
{
    char cFileName[]="abc.txt";
    displayFileSize(cFileName);

    return 0;
}


#3 -- ifstream

Though a C++ programmer would, of course, use ifstream rather than fopen, fseek, etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <fstream>
using namespace std;

void displayFileSize(const char *cFileName)
{
    ifstream ifs(cFileName);
    if(!ifs.is_open())
    {
        cout << "fopen_s failed" << endl;
        return;
    }
    if(ifs.seekg(0, ifstream::end))
    {
        long filesize = ifs.tellg();
        if(filesize == -1)
            cout << "tellg failed" << endl;
        else
            cout << "tellg returned : " << filesize << endl;
        ifs.seekg(0, ifstream::beg); // to be tidy
    }
    else
    {
        cout << "seekg failed" << endl;
    }
    // ifs's destructor closes the file
}

int main()
{
    char cFileName[]="abc.txt";
    displayFileSize(cFileName);

    return 0;
}


#4 -- Win32

For completeness, a more finished Win32 version:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
using namespace std;

void displayFileSize(const char *cFileName)
{
    HANDLE hFile=CreateFileA(cFileName,
                             GENERIC_READ,
                             FILE_SHARE_READ,
                             NULL, // use default security
                             OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL,
                             NULL); // no template file (handle)
    if(hFile==INVALID_HANDLE_VALUE)
    {
        cout << "CreateFile failed" << endl;
        return;
    }

    LARGE_INTEGER filesize = {0};
    BOOL b=GetFileSizeEx(hFile,&filesize);
    if(b)
        cout << "GetFileSizeEx returned : " << filesize.QuadPart << endl;
    else
        cout << "GetFileSizeEx failed" << endl;

    CloseHandle(hFile);
}

int main()
{
    char cFileName[]="abc.txt";
    displayFileSize(cFileName);

    return 0;
}
Last edited on
Topic archived. No new replies allowed.