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;
}
|