1,写入数据
最开始是在写入数据前先写入三个字节
BYTE btHead[] = { 0xEF,0xBB,0xBF };
::WriteFile(hFile, btHead, 3, &dwWrite, 0);
::WriteFile(hFile, str, lstrlen(str)*sizeof(TCHAR), &dwWrite, 0);
这样写入后文件样式为:
格式是UTF-8,但后面有个BOM,而且汉字也是乱码,
最后我又测试了下用c语言写入UTF-8数据,
//打开文件,按指定编码格式打开
FILE* fp=fopen("UTF_8Test.txt", "wt+,ccs=UTF-8");
//写入数据
TCHAR str[] = TEXT("测试文件,1234,abcd,ABCD");
fwrite(str, sizeof(TCHAR), lstrlen(str), fp);
//关闭
fclose(fp);
汉字不是乱码了,但是格式仍然是UTF-8 BOM
这就是不我想要的效果。
最后查找一翻资料后,
1。先把要保存的字符串转化为UTF-8格式的char字符串
2。在写入char字符串到文件中
//lpBuffer是传来的宽字符串的指针
//nBufferLeng是字符串的字符个数(用lstrlen求出的长度)
//求字符串转为UTF-8的字符长度
int size = ::WideCharToMultiByte(CP_UTF8, 0, (LPTSTR)lpBuffer, nBufferLeng, NULL, 0, NULL,
NULL);
//再转为char字符串
char* pTem = new char[size+1];
memset(pTem, 0, size);
::WideCharToMultiByte(CP_UTF8, 0, (LPTSTR)lpBuffer, nBufferLeng, pTem, size, nullptr, nullptr);
pTem[size] = '\0';
//最后写入char字符串
bResult = ::WriteFile(m_hFile, pTem, size, &dwWrite, 0);
delete[] pTem;
这样写入文件的效果:
这样汉字就不会出现乱码了,格式也是UTF-8,没有后面的BOM了
2。读取数据
数据的读取和写入一样,先读取数据到char数组中,再转为UTF-8格式的宽字符串中
//获得文件字节长度
int n = GetFileSize();
//写入char数组中
char* pChar = new char[n+1];
bResult = ::ReadFile(m_hFile, pChar, n, &dwRead, 0);
pChar[n] = '\0';
//计算字符串转UTF-8的字符长度
int len = MultiByteToWideChar(CP_UTF8, 0, pChar, strlen(pChar), nullptr, 0);
//转为TCHAR字符数组
TCHAR* pWChar = new TCHAR[len+1];
memset(pWChar, 0, len);
MultiByteToWideChar(CP_UTF8, 0, pChar, strlen(pChar), pWChar, len);
pWChar[len] = '\0';
//拷贝到函数外面的字符指针
lstrcpy((LPTSTR)lpBuffer, pWChar);
//清除内存
delete[] pWChar;
delete[] pChar;
读取数据的效果:
4。完整代码片段
QFile.h文件
//文件操作类
// 对Ascii,Unicode,UTF_8,Binary
// 四种文件格式的读写
class QFile
{
public:
QFile();
~QFile();
public:
enum OpenModule //文件打开模式
{
Read = GENERIC_READ, //只读模式
Write = GENERIC_WRITE, //只写模式
WriteRead = GENERIC_WRITE | GENERIC_READ //读写模式
};
enum FileEncoded //文件编码
{
enAnsii=0, //Ansi编码
enUnicode, //Unicode编码
enUTF_8, //UTF——8编码
enBinary //二进制编码
};
public:
//以指定模式打开文件
BOOL Open(const TCHAR* pFileName, OpenModule openModule);
void Close();
BOOL FileExists(const TCHAR* pFileName);//检查文件是否存在
BOOL CreateNewFile(const TCHAR* pFileName); //创建新文件
//以指定编码格式写入数据
int WriteFile(void* lpBuffer, int nBufferLeng, FileEncoded encodedType);
//以指定编码格式读取数据
int ReadFile(void* lpBuffer, int nBufferLeng, FileEncoded encodedType);
//获得文件的字节长度
int GetFileSize()const;
public:
HANDLE m_hFile;
};
QFile.cpp文件
//写入数据
int QFile::WriteFile(void* lpBuffer, int nBufferLeng, FileEncoded encodedType)
{
if (lpBuffer == nullptr)
return -1;
if (m_hFile == INVALID_HANDLE_VALUE)
return -1;
DWORD dwWrite = 0;
BOOL bResult = FALSE;
//编码UTF-8的写入
if (encodedType == enUTF_8)
{
int size = ::WideCharToMultiByte(CP_UTF8, 0, (LPTSTR)lpBuffer, nBufferLeng, NULL, 0, NULL,
NULL);
char* pTem = new char[size];
memset(pTem, 0, size);
::WideCharToMultiByte(CP_UTF8, 0, (LPTSTR)lpBuffer, nBufferLeng, pTem, size, nullptr, nullptr);
pTem[size] = '\0';
bResult = ::WriteFile(m_hFile, pTem, size, &dwWrite, 0);
return bResult ? dwWrite : -1;
}
//Unicode编码先写入两个字节,再写入数据
if (encodedType == enUnicode)
{
BYTE btHead[] = { 0xFF,0xFE };
bResult = ::WriteFile(m_hFile, btHead, 2, &dwWrite, 0);
}
//其他的都是直接写入数据
bResult = ::WriteFile(m_hFile, lpBuffer, nBufferLeng, &dwWrite, 0);
return bResult ? dwWrite : -1;
}
//读取数据
int QFile::ReadFile(void* lpBuffer, int nBufferLeng, FileEncoded encodedType)
{
if (lpBuffer == nullptr)
return -1;
if (m_hFile == INVALID_HANDLE_VALUE)
return -1;
DWORD dwRead = 0;
BOOL bResult = FALSE;
//编码格式UTF-8的读取
if (encodedType == enUTF_8)
{
char* pChar = new char[nBufferLeng +1];
bResult = ::ReadFile(m_hFile, pChar, nBufferLeng, &dwRead, 0);
pChar[nBufferLeng] = '\0';
int len = MultiByteToWideChar(CP_UTF8, 0, pChar, strlen(pChar), nullptr, 0);
TCHAR* pWChar = new TCHAR[len+1];
memset(pWChar, 0, len);
MultiByteToWideChar(CP_UTF8, 0, pChar, strlen(pChar), pWChar, len);
pWChar[len] = '\0';
lstrcpy((LPTSTR)lpBuffer, pWChar);
delete[] pWChar;
delete[] pChar;
return bResult ? dwRead : -1;
}
//编码Unicode,先跳过前两个字节再读取数据
if (encodedType == enUnicode)
{
SetFilePointer(m_hFile, 2, 0, FILE_BEGIN);
}
bResult = ::ReadFile(m_hFile, lpBuffer, nBufferLeng, &dwRead, 0);
return bResult ? dwRead : -1;
}
//…………
5。使用
//1.写入数据
QFile f;
f.Open(Utf_8Txt, QFile::Write);
TCHAR str[] = TEXT("测试数据,1234,ABCD");
f.WriteFile(str, lstrlen(str), QFile::enUTF_8);
f.Close();
//2.读取数据
QFile f;
f.Open(Utf_8Txt, QFile::Read);
TCHAR str[20] = { 0 };
int nLeng = f.GetFileSize();
f.ReadFile(str, nLeng, QFile::enUTF_8);
f.Close();
MessageBox(nullptr, str, TEXT("数据的读取"), 0);