如何很快将文件转换成另外一种编码格式?编码?按指定编码格式编译?如何检测文件编码格式?Java .class文件编码和JVM运行期内存编码?

如何很快将文件转换成另外一种编码格式?

  • 利用VS Code右下角的"选择编码"功能,选择"通过编码保存"可以很方便将文件转换成另外一种编码格式。尤其,在测试w/ BOM或w/o BOM, 或者ANSI编码和UTF编码转换,特别方便。
  • VS文件另存为有高级保存选项,如下:

编码

大家都遇到过乱码,本质在于默认和使用的字符集不同,用不同的编码在交流。尽管Unicode是世界标准,但它在某些场合未必是最优的编码,不一定会采用。

编码举例

比如python.py:

s = '你好'

$ hexdump -c python.py

0000000 s = ' 344 275 240 345 245 275 ' \r \n

每个中文是3个字节,是UTF-8编码。

源代码的编码

  • VS2019: C语言代码开头默认插入EF BB BF标志(BOM标志), 代表UTF-8编码。如果修改为Unicode Little Endian编码保存,代码开头会被插入FF FE.
  • Javac提供-encoding编译选项指定代码编码。
  • HTML提供charset属性指定编码格式。

乱码的本质

  • 以Python为例:从源代码角度,程序员写完之后保存编码格式A,放到Python解释器运行,它按编码格式B解析,最终输出的结果也可能在命令行窗口展示,它使用编码C. 只有A/B/C都适配,结果才是预期。

BOM标记

  • 为了更清晰标明字符编码,引入了BOM ( Byte-Order Mark). BOM的设计高明之处在于它将字符编码信息放在文件开头,而非文件之外,强制要求对字符编码的判断。注意,BOM只对UTF-16和UTF-8有效,对其他编码是无效的。

按指定编码格式编译?

当源代码编码格式是xxx时,gcc可以用参数-finput-charset=xxx用xxx编码格式编译。例如源代码并不是UTF-8,是UTF-16LE,可以用gcc -finput-charset=UTF-16LE demo.c编译。所有可支持的编码格式可以通过iconv -l获取。

当然,对于gcc, 如果仅仅用新的编码格式,你大概率会遇到编译错误。原因是你可能包含了系统头文件,而它们是用默认UTF-8编码的。

如果是VS,就没有这样的烦恼,它可以自动检测编码,即使是UTF-16LE编码,可以用cl.exe demo.c轻松编译通过,不用特别指定编码。但对于UTF-8,必须是带BOM头,否则也会编译错误。

指定并编译编码格式为UTF-16LE源代码,依然报错?

如何检测文件编码格式?

世界无奇不有,编码格式也五花八门,在预先不知道编码格式的情况下,检测编码格式除了靠一些特定标志,剩下的就是靠猜。

  • Unicode世界有BOM头,凭此可以找到编码格式。
  • 某些文件在开头有编码指示,例如XML和HTML有charset的说明。
  • 利用编程语言的字符编码检测库,例如Python的chardet库,Node.js中的jschardet库等。
  • 利用file -i命令猜测文件编码。
  • 许多文本编辑器,例如Visual Studio Code,Notepad++, Sublime Text等,具有检测文件编码的功能。当你打开一个文件时,编辑器通常会自动检测编码,并可以点击右下角的编码格式选择新的编码。
  • 利用在线编码检测网站,例如file-encode-detect.

Java .class文件编码和JVM运行期内存编码

  • Java源代码可以是任意编码格式,javac需要指定编码格式-encoding即可正确编译。
  • javac编译出.class文件是UTF-8编码。
  • JVM读取.class文件加载到内存中,编码格式为UTF-16.
  • java执行.class文件使用默认字符串输出(Windows平台是GBK),如对应的终端或显示设备编码不同,使用-Dfile.encoding=xxx指定编码。

若文章对您有帮助,欢迎关注 程序员小迷 。助您在编程路上越走越好!

微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。

我是 程序员小迷 (致力于C、C++、C#、Android、iOS、Java、Kotlin、Objective-C、Swift、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。

相关推荐
SL_staff15 分钟前
低代码选型避坑指南:为什么‘能拖拽’不等于‘能交付’?——基于JVS八大引擎的四维交付能力评估框架
java·低代码·spring cloud
2601_9669496521 分钟前
如何判断实时行情数据是否已经更新?从时间戳、交易时段到行情有效性
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
All for pursuit.23 分钟前
【位运算-3】136.只出现一次的数字
数据结构·c++·算法·leetcode
MoRanzhi120323 分钟前
106.正则问题(分治)
python·算法·正则表达式·蓝桥杯·递归·分治算法·字符串处理
李福春32 分钟前
技术思考问题6:技术演讲该晒成功架构,还是交代失败与取舍?
java·开发语言·架构·computer use·深圳同盟·腾讯云架构师技术同盟·反演思维
Pingred44 分钟前
我把一个私有化 RAG 系统真正跑通了:LocalRAG v0.1.0 发布
人工智能·python
Dmz丶1 小时前
前端转 AI 100 天 Day 24:API 测试——用 httpx + pytest 测 FastAPI
python
用户7771298509121 小时前
equals和==的区别
java