当前位置: 首页 > news >正文

Windows使用UTF-16,创建UTF-16文件请设置前两个字节为0xfffe,这是UTF-16的BOM码

windows下的Unicode是UTF-16,每个字都用两个字节来表示。编程的时候,通过TEXT宏,以及在项目中定义Unicode, _Unicode变量,就可以保证整个项目都是在Unicode下工作。

现在在将字符串写入文件的时候,发生了一些问题。写文件用的是WriteFile函数,字符串本身都是UTF-16的,写入文件后发现用vim和记事本打开都无法正确显示。用16进制的方式查看,每个字都是对的,都是2个字节,如果是英文字母,第二个字节就是00。

google 了一下,发现了答案。要在文件开头写入0xfffe,这是Unicode file的identifier,windows下的记事本和写字板读到这个头之后,就能正确识别这是一个Unicode文件了。所以,在代码中,创建文 本文件的时候,要多写这样一段(用ScheduleDownload的logger.cpp来做个例子):


                     //  logfile doesn't exist, create it, that's all
          hFile  =  CreateFile(log_file_path, GENERIC_WRITE, NULL, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
          
if  (hFile  ==  INVALID_HANDLE_VALUE) {
             operate_result 
=  FALSE;
          } 
else  {
             
//  write 0xfffe at the beginning of the file, this makes Notepad reads Unicodes well
             WORD unicode_identifier  =   0xfeff ;
             
if  (WriteFile(hFile,  & unicode_identifier,  sizeof (WORD),  & bytes_written, NULL)) {
                operate_result 
=  TRUE;
             } 
else  {
                operate_result 
=  FALSE;
             }
          }
          
goto  finished;

    finished:
       
if  (hFile  !=  NULL  &&  hFile  !=  INVALID_HANDLE_VALUE)
          CloseHandle(hFile);
       
return  operate_result;

 

这里不要奇怪为什么设置给unicode_identifier变量的值是0xfeff,这是因为x86是little endian,所以代码中的oxfeff存在寄存器中,然后设置到内存的时候,从低地址到高地址就变成了fffe,这样最后将这个WORD写入文件之后就 正好是fffe了。

最后我自己又测试了一下,写入中文也是没有问题的。使用gvim来打开的话需要设置一下,我在Ubuntu下打开文件是OK的,windows下的gvim的.vimrc设置和Ubuntu一样的话,应该也是没问题的。

转载于:https://www.cnblogs.com/super119/archive/2011/04/10/2011406.html

相关文章:

  • 把Linux高可用性请入你的数据中心
  • jQuery插件——图片按比例自适应缩放
  • Highcharts:高交互性的javascript图表类库
  • ASP.NET中文乱码的三个解决方案
  • 一招一式攻克linux(二)
  • 知识点 - Attribute在.net编程中的应用
  • Quartz2.1.5学习(一)
  • yahoo排名策略
  • 软件架构
  • 使用Scom监控Linux主机
  • javaScript中with含义与用法
  • lvy打包到本地
  • 具有键“Shape”的 ViewData 项属于类型“System.String”,但它必须属于类型“IEnumerableSelectListItem”。...
  • 对于Linux操作系统进行合理分区建议
  • 格式化字符串
  • 【Linux系统编程】快速查找errno错误码信息
  • 2018一半小结一波
  • Android开源项目规范总结
  • es的写入过程
  • Invalidate和postInvalidate的区别
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • Javascript基础之Array数组API
  • JavaScript设计模式系列一:工厂模式
  • JAVA之继承和多态
  • MySQL-事务管理(基础)
  • Node 版本管理
  • Object.assign方法不能实现深复制
  • react 代码优化(一) ——事件处理
  • SQLServer插入数据
  • Vue学习第二天
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 闭包--闭包之tab栏切换(四)
  • 记一次删除Git记录中的大文件的过程
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 思考 CSS 架构
  • 一、python与pycharm的安装
  • 云大使推广中的常见热门问题
  • kubernetes资源对象--ingress
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • 选择阿里云数据库HBase版十大理由
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • #14vue3生成表单并跳转到外部地址的方式
  • (笔试题)分解质因式
  • (附源码)php投票系统 毕业设计 121500
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转载)hibernate缓存
  • (转载)OpenStack Hacker养成指南
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • ****Linux下Mysql的安装和配置
  • ***检测工具之RKHunter AIDE
  • .net快速开发框架源码分享
  • @Service注解让spring找到你的Service bean
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择