1. 程式人生 > >win32API 讀寫ANSI\UNICODE\UNICODE BIG-ENDIAN\UTF-8格式文字

win32API 讀寫ANSI\UNICODE\UNICODE BIG-ENDIAN\UTF-8格式文字

#include <windows.h>
#include <tchar.h>
#include <cassert>



////////////////////////////////////////////////////
//
//			    讀寫檔案的簡單API函式封裝
//                  CFileBaseHelper
//                           |
//                  -----------------
//                 |                 |
//          CFileReadHelper   CFileWriteHelper
//
/////////////////////////////////////////////////////


////////////////////////////////////////////////
//基類
enum FileTextType
{
	enANSI,				//
	enUTF8,				//EF BB BF
	enUnicode,			//FF FE
	enUnicodeBigEndian,	//FE FF
	enUnknown
};

class CFileBaseHelper
{
public:
	CFileBaseHelper( LPCTSTR lpFileName);
	~CFileBaseHelper();
	void CloseFile();

protected:
	FileTextType GetFileTextType(LPCTSTR lpFileName );

	FileTextType m_fttTextType;
	HANDLE m_hFile;
};

CFileBaseHelper::CFileBaseHelper( LPCTSTR lpFileName )
	:m_fttTextType( enUnknown ), m_hFile( INVALID_HANDLE_VALUE )
{
	assert( lpFileName != NULL );
	if( lpFileName == NULL )
	{
		return;
	}

	m_fttTextType = GetFileTextType(lpFileName);

	//開啟檔案
	m_hFile = CreateFile( lpFileName, 
		GENERIC_READ|GENERIC_WRITE, 
		FILE_SHARE_READ,
		NULL,
		OPEN_EXISTING, 
		0, 
		NULL );

}

CFileBaseHelper::~CFileBaseHelper()
{
	CloseFile();
}

void CFileBaseHelper::CloseFile()
{
	if( m_hFile != INVALID_HANDLE_VALUE )
	{
		CloseHandle( m_hFile );
		m_hFile = INVALID_HANDLE_VALUE;
	}
}



/*****************************************************************
* 時    間: [2015年11月1日]
* 作    者:shanql
* 函式描述:獲取文字型別
* 函式引數:
* 函式返回:
*****************************************************************/
FileTextType CFileBaseHelper::GetFileTextType( LPCTSTR lpFileName )
{
	if( !lpFileName )
	{
		return enUnknown;
	}

	FileTextType fttTextType = enUnknown;

	//open file to read three byte 
	HANDLE hFile = CreateFile( lpFileName, 
		GENERIC_READ, 
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL, 
		OPEN_EXISTING, NULL, NULL );

	BYTE cbFlag[3] = { 0 };
	DWORD dwByteRead = 0;
	if( INVALID_HANDLE_VALUE != hFile &&
		ReadFile( hFile, cbFlag, 3, &dwByteRead, NULL ))
	{
		if( cbFlag[0] == 0xFF &&
			cbFlag[1] == 0xFE )
		{
			fttTextType = enUnicode;
		}
		else if ( cbFlag[0] == 0xFE &&
			cbFlag[1] == 0xFF )
		{
			fttTextType = enUnicodeBigEndian;
		}
		else if ( cbFlag[0] == 0xEF &&
			cbFlag[1] == 0xBB &&
			cbFlag[2] == 0xBF )
		{
			fttTextType = enUTF8;
		}
		else 
		{
			fttTextType = enANSI;
		}
	}

	CloseHandle( hFile );
	return fttTextType;
}



///////////////////////////////////////
//讀檔案類
class CFileReadHelper:public CFileBaseHelper
{
public:
	CFileReadHelper( LPCTSTR lpFileName);
	BOOL ReadFile( LPVOID lpBuffer, DWORD dwByteToRead, LPDWORD lpByteRead );	
};

CFileReadHelper::CFileReadHelper( LPCTSTR lpFileName )
	:CFileBaseHelper( lpFileName )
{

}

BOOL CFileReadHelper::ReadFile( LPVOID lpBuffer, DWORD dwByteToRead, LPDWORD lpByteRead )
{
	assert( m_hFile != INVALID_HANDLE_VALUE );
	if( m_hFile == INVALID_HANDLE_VALUE )
	{
		return FALSE;
	}

	assert( lpBuffer != NULL );
	if( lpBuffer == NULL )
	{
		return FALSE;
	}

	BOOL bReadResult = FALSE;
	switch( m_fttTextType )
	{
	case enANSI:
		{
			bReadResult = ::ReadFile( m_hFile, 
				lpBuffer, dwByteToRead, lpByteRead, NULL );
			break;
		}
	case enUnicode:
	case enUnicodeBigEndian:
		{
			//跳過前2個標記位元組
			if( INVALID_SET_FILE_POINTER == SetFilePointer( m_hFile, 2, 0, FILE_BEGIN) )
			{
				if( GetLastError() != NOERROR )
				{
					return FALSE;
				}
			}

			bReadResult = ::ReadFile( m_hFile, 
				lpBuffer, dwByteToRead, lpByteRead, NULL );

			break;
		}
	case enUTF8:
		{
			//跳過前3個標記位元組
			if( INVALID_SET_FILE_POINTER == SetFilePointer( m_hFile, 3, 0, FILE_BEGIN) )
			{
				if( GetLastError() != NOERROR )
				{
					return FALSE;
				}
			}

			bReadResult = ::ReadFile( m_hFile, 
				lpBuffer, dwByteToRead, lpByteRead, NULL );
			break;
		}
	default:
		{
			assert( false );
			return FALSE;
		}
	}

	return bReadResult;
}


//////////////////////////////////////////
//寫檔案類
class CFileWriteHelper : public CFileBaseHelper
{
public:
	CFileWriteHelper( LPCTSTR lpFileName);
	BOOL WriteFile( LPVOID lpBuffer, DWORD dwByteToWrite, LPDWORD lpByteWrite );
};

CFileWriteHelper::CFileWriteHelper( LPCTSTR lpFileName )
	:CFileBaseHelper( lpFileName )
{

}

BOOL CFileWriteHelper::WriteFile( LPVOID lpBuffer, DWORD dwByteToWrite, LPDWORD lpByteWrite )
{
	assert( m_hFile != INVALID_HANDLE_VALUE );
	if( m_hFile == INVALID_HANDLE_VALUE )
	{
		return FALSE;
	}

	assert( lpBuffer != NULL );
	if( lpBuffer == NULL )
	{
		return FALSE;
	}

	BOOL bWriteResult = FALSE;
	switch( m_fttTextType )
	{
	case enANSI:
		{
			bWriteResult = ::WriteFile( m_hFile, 
				lpBuffer, dwByteToWrite, lpByteWrite, NULL );
			break;
		}
	case enUnicode:
		{	
			if( INVALID_SET_FILE_POINTER == SetFilePointer( m_hFile, 0, 0, FILE_BEGIN) )
			{
				if( GetLastError() != NOERROR )
				{
					return FALSE;
				}
			}

			//在檔案頭先寫入兩個位元組的標記 FF FE
			DWORD dwWriteHead = 0;
			BYTE cbHeadFlag[] = { 0xFF, 0xFE };
			if( !::WriteFile( m_hFile, cbHeadFlag, 2, &dwWriteHead, NULL ))
			{
				return FALSE;
			}

			bWriteResult = ::WriteFile( m_hFile, lpBuffer, dwByteToWrite, lpByteWrite, NULL );

			break;
		}
	case enUnicodeBigEndian:
		{
			if( INVALID_SET_FILE_POINTER == SetFilePointer( m_hFile, 0, 0, FILE_BEGIN) )
			{
				if( GetLastError() != NOERROR )
				{
					return FALSE;
				}
			}

			//在檔案頭先寫入兩個位元組的標記 FE FF
			DWORD dwWriteHead = 0;
			BYTE cbHeadFlag[] = { 0xFE, 0xFF };
			if( !::WriteFile( m_hFile, cbHeadFlag, 2, &dwWriteHead, NULL ))
			{
				return FALSE;
			}

			bWriteResult = ::WriteFile( m_hFile, lpBuffer, dwByteToWrite, lpByteWrite, NULL );

			break;
		}
	case enUTF8:
		{
			if( INVALID_SET_FILE_POINTER == SetFilePointer( m_hFile, 0, 0, FILE_BEGIN) )
			{
				if( GetLastError() != NOERROR )
				{
					return FALSE;
				}
			}

			//在檔案頭先寫入3個位元組的標記 EF BB BF
			DWORD dwWriteHead = 0;
			BYTE cbHeadFlag[] = { 0xEF, 0xBB, 0xBF };
			if( !::WriteFile( m_hFile, cbHeadFlag, 3, &dwWriteHead, NULL ))
			{
				return FALSE;
			}

			bWriteResult = ::WriteFile( m_hFile, lpBuffer, dwByteToWrite, lpByteWrite, NULL );

			break;
		}
	default:
		{
			assert( false );
			return FALSE;
		}
	}

	return bWriteResult;
}


//測試函式 
void ReverseFileTest( LPCTSTR lpFileName )
{
	assert( lpFileName != NULL );
	if( lpFileName == NULL )
	{
		return;
	}

	CFileReadHelper tmpFileRead( lpFileName );
	BYTE szReadBuffer[1024] = { 0 };
	DWORD dwByteRead = 0;
	if( !tmpFileRead.ReadFile( szReadBuffer, sizeof(szReadBuffer), &dwByteRead ) )
	{
		_tprintf( TEXT("read file failed.\r\n"));
		return;
	}
	tmpFileRead.CloseFile();//可以不呼叫,析構時會自動呼叫


	//反轉檔案內容
	INT nStart = 0;
	INT nEnd = dwByteRead-1;
	BYTE cbTemp;
	while( nStart < nEnd )
	{
		cbTemp = szReadBuffer[nStart];
		szReadBuffer[nStart] = szReadBuffer[nEnd];
		szReadBuffer[nEnd] = cbTemp;

		++nStart;
		--nEnd;
	}

	//寫入檔案
	CFileWriteHelper tmpFileWrite( lpFileName );
	DWORD dwByteWrite = 0;
	if( !tmpFileWrite.WriteFile( szReadBuffer, dwByteRead, &dwByteWrite ) )
	{
		_tprintf( TEXT("write file failed.\r\n") );
		return;
	}
	tmpFileWrite.CloseFile();//可以不呼叫,析構時會自動呼叫
}


int main()
{
	ReverseFileTest(TEXT("test_ansi.txt"));
	ReverseFileTest(TEXT("test_unicode.txt"));
	ReverseFileTest(TEXT("test_unicode_big_endian.txt"));
	ReverseFileTest(TEXT("test_utf8.txt"));
	return 0;
}

作者:山丘兒
轉載請標明出處,謝謝。原文地址:http://blog.csdn.net/s634772208/article/details/49563341