With Windows is probably better to use the Win32 API for files.
I attach a class for working with files under win32
using the win 32 API. If you read the code you'll understand
how to work with it.
----------- header -------------------
#ifndef DISKFILE_H
#define DISKFILE_H
#if _MSC_VER > 1000
#pragma warning (disable: 4786)
#pragma warning (disable: 4748)
#pragma warning (disable: 4103)
#endif /* _MSC_VER > 1000 */
#include <afx.h>
#include <afxwin.h>
#define FILE_WIN_LINE_END 0x00000000
#define FILE_UNIX_LINE_END 0x00000001
#define FILE_DEF_MEM_SIZE 0x000FFFFF
#define FILE_DEF_MEM_ALL_SIZE 0x0000FFFF
#define FILE_DEF_LINE_SIZE 0x00001000
#define FILE_DEF_PATH_SIZE MAX_PATH
#define FILE_ATTRIBUTE_FAIL 0xFFFFFFFF
#define FILE_DEF_END_PTR 0xFFFFFFFF
#define CODE_FILE_MOVETO 0x0001
#define CODE_FILE_RESETP 0x0002
#define CODE_FILE_END 0x0003
#define DISKFILE32_ERRCODE_OK 0
#define DISKFILE32_ERRCODE_UNKNOWNERROR 1
#define DISKFILE32_ERRCODE_NOFILEPATH 2
#define DISKFILE32_ERRCODE_FILEIO 3
#define DISKFILE32_ERRCODE_DELETEFILE 4
#define DISKFILE32_ERRCODE_EOF 5
#define DISKFILE32_ERRCODE_APPENDTODISK_OPEN 6
#define DISKFILE32_ERRCODE_APPENDTODISK_WRITE 7
#define DISKFILE32_ERRCODE_GETFILESIZE_OPEN 8
#define DISKFILE32_ERRCODE_GETFILESIZE_DO 9
#define DISKFILE32_ERRCODE_READ_OPEN 10
#define DISKFILE32_ERRCODE_READ_SETPOINTER 11
#define DISKFILE32_ERRCODE_READ_DO 12
#define DISKFILE32_ERRCODE_WRITE_OPEN 13
#define DISKFILE32_ERRCODE_WRITE_SETPOINTER 14
#define DISKFILE32_ERRCODE_WRITE_DO 15
#define DISKFILE32_ERRCODE_APPEND_OPEN 16
#define DISKFILE32_ERRCODE_APPEND_WRITE 17
#define DISKFILE32_ERRCODE_NOBUFFER 18
class CDiskFile32
{
private:
UINT32 unLastErrorCode;
bool bEndOfFile;
UINT32 unPointer;
TCHAR cbFilePath[FILE_DEF_PATH_SIZE];
public:
CDiskFile32();
~CDiskFile32();
UINT32 GetLastErrorCode(void);
void SetFilePath(TCHAR *psFilePath);
void GetFilePath(TCHAR *psFilePath);
bool CheckFileExistence(void);
void Erase(void);
UINT32 GetSize(void);
bool GetEndOfFile(void);
void SetPointer(UINT32 unOffset, UINT32 unCode);
UINT32 GetPointer(void);
void Read (void *pMemBuffer, UINT32 unBytesTo, UINT32 *punBytesDone);
void Write (void *pMemBuffer, UINT32 unBytesTo, UINT32 *punBytesDone);
void Append(void *pMemBuffer, UINT32 unBytesTo);
};
#endif /* ! defined (DISKFILE_H) */
----------- implementation -------------------
#include "StdAfx.h"
#include "DiskFile32.h"
CDiskFile32::CDiskFile32()
{
unLastErrorCode = DISKFILE32_ERRCODE_OK;
bEndOfFile = false;
unPointer = 0;
#if defined (UNICODE)
FillMemory(cbFilePath, 2*FILE_DEF_PATH_SIZE, 0);
#else
FillMemory(cbFilePath, FILE_DEF_PATH_SIZE, 0);
#endif
}
CDiskFile32::~CDiskFile32()
{
}
UINT32 CDiskFile32::GetLastErrorCode(void)
{
return unLastErrorCode;
}
void CDiskFile32::SetFilePath(TCHAR *psFilePath)
{
_tcsncpy(cbFilePath, psFilePath, FILE_DEF_PATH_SIZE-1);
}
void CDiskFile32::GetFilePath(TCHAR *psFilePath)
{
_tcsncpy(psFilePath, cbFilePath, FILE_DEF_PATH_SIZE-1);
*(psFilePath+FILE_DEF_PATH_SIZE-1) = L'\0';
}
bool CDiskFile32::CheckFileExistence(void)
{
if ( ! _tcslen(cbFilePath) )
{
unLastErrorCode = DISKFILE32_ERRCODE_NOFILEPATH;
}
return (GetFileAttributes(cbFilePath) != FILE_ATTRIBUTE_FAIL);
}
void CDiskFile32::Erase(void)
{
unLastErrorCode = DISKFILE32_ERRCODE_UNKNOWNERROR;
try
{
if ( ! _tcslen(cbFilePath) )
{
unLastErrorCode = DISKFILE32_ERRCODE_NOFILEPATH;
}
if ( ! DeleteFile(cbFilePath) )
{
unLastErrorCode = DISKFILE32_ERRCODE_DELETEFILE;
}
}
catch(...)
{
unLastErrorCode = DISKFILE32_ERRCODE_DELETEFILE;
}
unLastErrorCode = DISKFILE32_ERRCODE_OK;
}
UINT32 CDiskFile32::GetSize(void)
{
UINT32 unFileSize;
SECURITY_ATTRIBUTES SecurityAttributes;
HANDLE hFile;
unLastErrorCode = DISKFILE32_ERRCODE_UNKNOWNERROR;
try
{
if ( ! _tcslen(cbFilePath) )
{
unLastErrorCode = DISKFILE32_ERRCODE_NOFILEPATH;
}
SecurityAttributes.nLength = sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor = NULL;
SecurityAttributes.bInheritHandle = FALSE;
hFile = CreateFile(cbFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
&SecurityAttributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if ( INVALID_HANDLE_VALUE == hFile )
{
unLastErrorCode = DISKFILE32_ERRCODE_GETFILESIZE_OPEN;
}
unFileSize = (UINT32) GetFileSize(hFile, NULL);
if ( unFileSize == FILE_DEF_END_PTR )
{
unLastErrorCode = DISKFILE32_ERRCODE_GETFILESIZE_DO;
}
if ( INVALID_HANDLE_VALUE != hFile )
CloseHandle(hFile);
}
catch(...)
{
}
unLastErrorCode = DISKFILE32_ERRCODE_OK;
return unFileSize;
}
bool CDiskFile32::GetEndOfFile(void)
{
return bEndOfFile;
}
void CDiskFile32::SetPointer(UINT32 unOffset, UINT32 unCode)
{
switch(unCode)
{
case CODE_FILE_MOVETO:
unPointer = unOffset;
break;
case CODE_FILE_RESETP:
unPointer = 0;
break;
case CODE_FILE_END:
unPointer = FILE_DEF_END_PTR;
break;
}
bEndOfFile = false;
}
UINT32 CDiskFile32::GetPointer(void)
{
return unPointer;
}
void CDiskFile32::Read(void *pMemBuffer, UINT32 unBytesTo, UINT32 *punBytesDone)
{
DWORD dwBytesTo, dwBytesDone;
SECURITY_ATTRIBUTES SecurityAttributes;
HANDLE hFile;
UINT32 unFileSize;
BOOL bSucceded;
unLastErrorCode = DISKFILE32_ERRCODE_UNKNOWNERROR;
if ( NULL == pMemBuffer )
{
unLastErrorCode = DISKFILE32_ERRCODE_NOBUFFER;
return;
}
try
{
if ( ! _tcslen(cbFilePath) )
{
unLastErrorCode = DISKFILE32_ERRCODE_NOFILEPATH;
return;
}
SecurityAttributes.nLength = sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor = NULL;
SecurityAttributes.bInheritHandle = FALSE;
hFile = CreateFile(cbFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
&SecurityAttributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if ( INVALID_HANDLE_VALUE == hFile )
{
unLastErrorCode = DISKFILE32_ERRCODE_READ_OPEN;
throw;
}
unFileSize = (UINT32) GetFileSize(hFile, 0);
if ( (unPointer == FILE_DEF_END_PTR) || (unPointer > unFileSize) )
unPointer = unFileSize;
SetFilePointer(hFile, unPointer, 0, FILE_BEGIN);
bEndOfFile = false;
dwBytesTo = unBytesTo;
bSucceded = ReadFile(hFile, (LPVOID) pMemBuffer, dwBytesTo, &dwBytesDone, NULL);
if ( !bSucceded )
{
unLastErrorCode = DISKFILE32_ERRCODE_READ_DO;
throw;
}
if( INVALID_HANDLE_VALUE != hFile )
CloseHandle(hFile);
unPointer += dwBytesDone;
if(dwBytesDone != dwBytesTo)
bEndOfFile = true;
}
catch(...)
{
if( INVALID_HANDLE_VALUE != hFile )
CloseHandle(hFile);
return;
}
unLastErrorCode = DISKFILE32_ERRCODE_OK;
if ( punBytesDone )
*punBytesDone = (UINT32) dwBytesDone;
}
void CDiskFile32::Write(void *pMemBuffer, UINT32 unBytesTo, UINT32 *punBytesDone)
{
DWORD dwBytesTo, dwBytesDone;
SECURITY_ATTRIBUTES SecurityAttributes;
HANDLE hFile;
UINT32 unFileSize;
unLastErrorCode = DISKFILE32_ERRCODE_UNKNOWNERROR;
if ( NULL == pMemBuffer )
{
unLastErrorCode = DISKFILE32_ERRCODE_NOBUFFER;
return;
}
try
{
if ( ! _tcslen(cbFilePath) )
{
unLastErrorCode = DISKFILE32_ERRCODE_NOFILEPATH;
return;
}
SecurityAttributes.nLength = sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor = NULL;
SecurityAttributes.bInheritHandle = FALSE;
hFile = CreateFile(cbFilePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
&SecurityAttributes, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);
if ( INVALID_HANDLE_VALUE == hFile )
{
unLastErrorCode = DISKFILE32_ERRCODE_WRITE_OPEN;
throw;
}
unFileSize = (UINT32) GetFileSize(hFile, 0);
if (unPointer == FILE_DEF_END_PTR)
unPointer = unFileSize;
if (unPointer > unFileSize)
{
unLastErrorCode = DISKFILE32_ERRCODE_WRITE_SETPOINTER;
throw;
}
SetFilePointer(hFile, unPointer, NULL, FILE_BEGIN);
dwBytesTo = unBytesTo;
WriteFile(hFile, (LPVOID) pMemBuffer, dwBytesTo, &dwBytesDone, NULL);
if ( dwBytesDone < dwBytesTo )
{
unLastErrorCode = DISKFILE32_ERRCODE_WRITE_DO;
throw;
}
unPointer += dwBytesDone;
if ( INVALID_HANDLE_VALUE != hFile )
CloseHandle(hFile);
}
catch(...)
{
if ( INVALID_HANDLE_VALUE != hFile )
CloseHandle(hFile);
return;
}
unLastErrorCode = DISKFILE32_ERRCODE_OK;
if ( punBytesDone )
*punBytesDone = (UINT32) dwBytesDone;
}
void CDiskFile32::Append(void *pMemBuffer, UINT32 unBytesTo)
{
SECURITY_ATTRIBUTES SecurityAttributes;
DWORD dwBytesTo, dwBytesDone;
HANDLE hFile;
unLastErrorCode = DISKFILE32_ERRCODE_UNKNOWNERROR;
if ( NULL == pMemBuffer )
{
unLastErrorCode = DISKFILE32_ERRCODE_NOBUFFER;
return;
}
try
{
if ( ! _tcslen(cbFilePath) )
{
unLastErrorCode = DISKFILE32_ERRCODE_NOFILEPATH;
return;
}
SecurityAttributes.nLength = sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor = NULL;
SecurityAttributes.bInheritHandle = FALSE;
hFile = CreateFile(cbFilePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
&SecurityAttributes, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);
if ( INVALID_HANDLE_VALUE == hFile )
{
unLastErrorCode = DISKFILE32_ERRCODE_APPEND_OPEN;
throw;
}
SetFilePointer(hFile, 0, NULL, FILE_END);
dwBytesTo = unBytesTo;
WriteFile(hFile, (LPVOID) pMemBuffer, dwBytesTo, &dwBytesDone, 0);
if ( dwBytesDone != dwBytesTo )
{
unLastErrorCode = DISKFILE32_ERRCODE_APPEND_WRITE;
throw;
}
unPointer = (UINT32) GetFileSize(hFile, 0);
if( INVALID_HANDLE_VALUE != hFile )
CloseHandle(hFile);
}
catch(...)
{
if( INVALID_HANDLE_VALUE != hFile )
CloseHandle(hFile);
return;
}
unLastErrorCode = DISKFILE32_ERRCODE_OK;
}