win32 读写UTF-8格式的文件的方法

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
飞天下载系统FTDMSV5.0 软件介绍 软件名称:飞天下载系统(UTF-8) 软件版本:5.0版(具体版本程序中有标注)  软件性质:免费(仅限非商业使用) 开发环境:WIN2003+ASP+ACCESS2000 支持系统:WIN98/NT/2000/XP/2003及更高服务器版本系统 版权所有:CHINAYMZ.COM 程序制作:陈惠添 主页地址:http://www.ftbbs.org 演示地址:http://www.chinaymz.com(中国源码站) 功能简介 1、采用静态缓存技术,所有面页均由ASP快速一次性生成HTM。 2、采用符合Web2.0标准的XHTML+CSS开发而成。 3、生成所有页面均能通过XHTML+CSS校验! 4、支持FireFox,IE低版本浏览器,满足更多用户的需求。 5、提供RSS2.0订阅功能,无需浏览器,即可快速获得最新软件信息。 安装方法 1、下载FTDMS后,释放到如e:/ftdms/下,注意该版本是静态版所以主机空间一定要有fso的读写等操作权限。 2、建立虚拟站点(不要建虚拟目录)如ftdms,指向e:/ftdms同时要加入index.htm为默认首页. 3、把upload目录下的文件上传到站点根目录下或上传到你定义的目录下. 4、安装执行根目录下的setup.asp文件然后根据提示操作. 5、数据库连接配制文件是/config.asp安装后系统会根据你填写的连接参数自动配制请不要手工修改. 6、后台管理路径是admin.asp,管理员用户名和密码是安装时你所填写的。 7、为了安全安装成功后请给数据库改名,数据库在db目录下,配制文件是config.asp 8、创建文件存放目录(存放文件目录布局),如asp源码分类存放在asp目录下,那么就要在站点中创建asp文件夹. 注意:IIS需要启用父路径。
gdal-1.11.1支持proj-4.8.0和geos-3.4.2(vs2010+win7-32bit) =================================== GDAL编译说明 =================================== 功能描述:读写栅格和矢量数据格式 官方网站:http://www.gdal.org/ 下载地址:http://download.osgeo.org/gdal/ 编译平台:Window 7 (32位)+VisualStudio2010 GDAL编译步骤: 1、解压下载文件gdal-1.11.1.tar.gz到d:\gdal-1.11.1 2、新建文本文件gdal-build-vs2010.txt,重命名为gdal-build-vs2010.bat,输入以下命令: ----------------------------------------------------------- call "C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat" cd /d d:\gdal-1.11.1 nmake /f makefile.vc nmake /f makefile.vc install nmake /f makefile.vc devinstall ----------------------------------------------------------- 3、如需编译C#版本gdal,接着输入以下命令: ----------------------------------------------------------- cd /D d:\gdal-1.11.1\swig\csharp nmake /f makefile.vc ----------------------------------------------------------- 4、用文本编辑器打开nmake.opt文件,修改默认编译选项 1) 修改默认安装路径:GDAL_HOME = "C:\warmerda\bld" 2) 静态联编PORJ.4,删除#号注释,修改PROJ源代码路径和lib路径 -------------------------------------------------- PROJ_FLAGS = -DPROJ_STATIC PROJ_INCLUDE = -Id:\proj-4.8.0\src PROJ_LIBRARY = d:\proj-4.8.0\src\proj_i.lib -------------------------------------------------- 3) 支持GEOS,删除#号注释,并修改根路径、include路径和lib路径 -------------------------------------------------- GEOS_DIR=d:/geos-3.4.2 GEOS_CFLAGS = -I$(GEOS_DIR)/capi -I$(GEOS_DIR)/include -DHAVE_GEOS GEOS_LIB = $(GEOS_DIR)/src/geos_c_i.lib -------------------------------------------------- 注意:GDAL1.8.0以后版本不支持带中文的路径,1.7以前版本不存在这个问题。 解决办法是:调用GDALRegisterAll()和OGRAllRegiser()函数后,加上下面一句即可 CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); =================================== PROJ编译说明 =================================== 功能描述:投影转换 官方网站:http://trac.osgeo.org/proj/ 下载地址:http://download.osgeo.org/proj/ 编译平台:Window 7 (32位)+VisualStudio2010 编译步骤: 1、解压下载文件proj-4.8.0.zip到d:\proj-4.8.0 2、新建文本文件proj-build-vs2010.txt,重命名为proj-build-vs2010.bat,输入以下命令: -------------------------------------------------

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值