`

java编码浅释_转

    博客分类:
  • java
阅读更多

Java编码浅析

Java与Unicode:

 

Java的class文件采用utf8的编码方式,JVM运行时采用utf16。

 

Java的字符串是unicode编码的。

 

总之,Java采用了unicode字符集,使之易于国际化。

 

Java支持哪些字符集:

 

即Java能识别哪些字符集并对它进行正确地处理?

 

查看Charset 类,最新的JDK支持160种字符集。可以通过static方法availableCharsets拿到所有Java支持的字符集。

 
Java代码

   1. assertEquals(160, Charset.availableCharsets().size()); 
   2.  
   3. Set<String> charsetNames = Charset.availableCharsets().keySet(); 
   4.  
   5. assertTrue(charsetNames.contains("utf-8")); 
   6. assertTrue(charsetNames.contains("utf-16")); 
   7. assertTrue(charsetNames.contains("gb2312")); 
   8.  
   9. assertTrue(Charset.isSupported("utf-8")); 

assertEquals(160, Charset.availableCharsets().size());

Set<String> charsetNames = Charset.availableCharsets().keySet();

assertTrue(charsetNames.contains("utf-8"));
assertTrue(charsetNames.contains("utf-16"));
assertTrue(charsetNames.contains("gb2312"));

assertTrue(Charset.isSupported("utf-8"));

 

需要在哪些时候注意编码问题?

 

1. 从外部资源读取数据:

 

这跟外部资源采取的编码方式有关,我们需要使用外部资源采用的字符集来读取外部数据:

 
Java代码

   1. InputStream is = new FileInputStream("res/input2.data"); 
   2. InputStreamReader streamReader = new InputStreamReader(is, "GB18030"); 

InputStream is = new FileInputStream("res/input2.data");
InputStreamReader streamReader = new InputStreamReader(is, "GB18030");

 

这里可以看到,我们采用了GB18030编码读取外部数据,通过查看streamReader的encoding可以印证:

 
Java代码

   1. assertEquals("GB18030", streamReader.getEncoding()); 

assertEquals("GB18030", streamReader.getEncoding());

 

正是由于上面我们为外部资源指定了正确的编码,当它转成char数组时才能正确地进行解码(GB18030 -> unicode):

 
Java代码

   1. char[] chars = new char[is.available()]; 
   2. streamReader.read(chars, 0, is.available()); 

char[] chars = new char[is.available()];
streamReader.read(chars, 0, is.available());

 

但我们经常写的代码就像下面这样:

 
Java代码

   1. InputStream is = new FileInputStream("res/input2.data"); 
   2. InputStreamReader streamReader = new InputStreamReader(is); 

InputStream is = new FileInputStream("res/input2.data");
InputStreamReader streamReader = new InputStreamReader(is);

 

这时候InputStreamReader采用什么编码方式读取外部资源呢?Unicode?不是,这时候采用的编码方式是JVM的默认字符集,这个默认字符集在

虚拟机启动时决定,通常根据语言环境和底层操作系统的 charset 来确定。可以通过以下方式得到JVM的默认字符集:

 
Java代码

   1. Charset.defaultCharset(); 

Charset.defaultCharset();

 

为什么要这样?因为我们从外部资源读取数据,而外部资源的编码方式通常跟操作系统所使用的字符集一样,所以采用这种默认方式是可以理

解的。

 

好吧,那么我通过我的IDE Ideas创建了一个文件,并以JVM默认的编码方式从这个文件读取数据,但读出来的数据竟然是乱码。为何?呵呵,

其实是因为通过Ideas创建的文件是以utf-8编码的。要得到一个JVM默认编码的文件,通过手工创建一个txt文件试试吧。

 

2. 字符串和字节数组的相互转换

 

我们通常通过以下代码把字符串转换成字节数组:

 
Java代码

   1. "string".getBytes(); 

"string".getBytes();

 

但你是否注意过这个转换采用的编码呢?其实上面这句代码跟下面这句是等价的:

 
Java代码

   1. "string".getBytes(Charset.defaultCharset()); 

"string".getBytes(Charset.defaultCharset());

 

也就是说它根据JVM的默认编码(而不是你可能以为的unicode)把字符串转换成一个字节数组。

 

反之,如何从字节数组创建一个字符串呢?

 
Java代码

   1. new String("string".getBytes()); 

new String("string".getBytes());

 

同样,这个方法使用平台的默认字符集解码字节的指定数组(这里的解码指从一种字符集到unicode)。

 

 

字符串编码迷思:

 
Java代码

   1. new String(input.getBytes("ISO-8859-1"), "GB18030") 

new String(input.getBytes("ISO-8859-1"), "GB18030")

 

上面这段代码代表什么?有人会说: “把input字符串从ISO-8859-1编码方式转换成GB18030编码方式”。如果这种说法正确,那么又如何解释

我们刚提到的java字符串都采用unicode编码呢?

 

这种说法不仅是欠妥的,而且是大错特错的,让我们一一来分析,其实事实是这样的:我们本应该用GB18030的编码来读取数据并解码成字符串

,但结果却采用了ISO-8859-1的编码,导致生成一个错误的字符串。要恢复,就要先把字符串恢复成原始字节数组,然后通过正确的编码

GB18030再次解码成字符串(即把以GB18030编码的数据转成unicode的字符串)。注意,字符串永远都是unicode编码的。

 

但编码转换并不是负负得正那么简单,这里我们之所以可以正确地转换回来,是因为 ISO8859-1 是单字节编码,所以每个字节被按照原样 转

换为 String ,也就是说,虽然这是一个错误的转换,但编码没有改变,所以我们仍然有机会把编码转换回来!

 

总结:

 

所以,我们在处理java的编码问题时,要分清楚三个概念:Java采用的编码:unicode,JVM平台默认字符集和外部资源的编码。
声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。

分享到:
评论

相关推荐

    基于hadoop的百度云盘源代码(亲测可用完整项目代码)

    基于hadoop的百度云盘源代码(亲测可用完整项目代码),个人经导师指导并认可通过的毕业设计项目,评审分98分,项目中的源码都是经过本地编译过可运行的,都经过严格调试,确保可以运行!主要针对计算机相关专业的正在做毕业设计的学生和需要项目实战练习的学习者,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的百度云盘源代码(亲测可用完整项目代码)基于hadoop的

    cruise软件模型,串联混动ECMS,cruise增程混动仿真模型,A-ECMS控制策略,Cruise混动仿真模型,串联混动汽车动力性经济性仿真 关于模型 1.本模型是基于增程混动架构搭建的cru

    cruise软件模型,串联混动ECMS,cruise增程混动仿真模型,A-ECMS控制策略,Cruise混动仿真模型,串联混动汽车动力性经济性仿真。 关于模型 1.本模型是基于增程混动架构搭建的cruise仿真模型,串联混动架构,实现简易的A-ECMS控制,可用于相关策略开发及课题研究。 2.模型是基于cruise simulink搭建的base模型,策略模型基于MATLAB Simulink平台搭建完成,通过C++编译器编译成dll文件给CRUISE引用,实现联合仿真。 3.尽可能详细的描写了策略说明,大约14页左右,主要解释策略搭建逻辑及各模式间的转。 4.模型主要供学习使用,不同的车型控制策略必然不同,请不要抱着买来即用的态度拿后,具体车型仿真任务请根据需求自行变更模型,或联系模型定制。 5.使用模型前请确保有相应软件基础,卖的是模型,不是软件教程。 关于模型策略问题可以适当交流,但不做软件保姆式教学。 6.模型由“王浮生不怕生”搭建,拿后模型提供五天文字,盗版用户不提供,找谁买的问谁去。 7.文件包含:cruise模型、simulink策略模型、策略说明文档。 8.DLL文件使

    Java 21 新特性详解:虚拟线程、字符串模板与模式匹配等亮点

    Java 21 是一款里程碑式的版本,虚拟线程让高并发编程突破极限,字符串模板让文本处理更简单直观,模式匹配增强则彻底解放你的双手。加上性能优化、集合新功能,它不仅让开发更轻松,还能大幅提升应用运行效率。快来体验这个重新定义开发体验的版本吧!

    基于java的无人超市管理系统设计与实现.docx

    基于java的无人超市管理系统设计与实现.docx

    2021中国新锐品牌发展研究:食品饮料行业报告.pdf

    2021中国新锐品牌发展研究:食品饮料行业报告

    永磁同步电机FOC矢量控制4种方法模型:双闭环PI控制、电流滞环控制、转速环滑模控制、电流环PR控制4个simulink模型 三相永磁同步电机矢量控制Matlab Simulink仿真模型,带有各部分

    永磁同步电机FOC矢量控制4种方法模型:双闭环PI控制、电流滞环控制、转速环滑模控制、电流环PR控制4个simulink模型 三相永磁同步电机矢量控制Matlab Simulink仿真模型,带有各部分模块详细介绍文档及参考文献17篇。 内容非常全面,说明文档从转速电流双闭环PI控制开始介绍,同时含滞环电流控制、滑模速度控制、静止坐标系下电流PR控制的原理介绍、模型介绍、参数计算步骤、模块结构介绍和仿真波形分析。 方便对比加深理解,以及改进丰富内容。 总共含4个矢量控制(FOC)的Simulink仿真模型,清单如下: (1)一般矢量控制即转速环、电流环均采用PI调节器,则对应仿真模型PMSM_FOC_PI.slx文件。 (2)在(1)的基础上把电流环PI控制器成滞环控制,则对应仿真模型PMSM_Zhihuan.slx文件。 (3)把转速环PI控制器成滑模控制,则对应仿真模型PMSM_SMC.slx文件。 (4)若电流控制中不采用坐标变,把电流环PI控制器成PR控制器,则对应仿真模型PMSM_PR.slx。 Matlab2015b以上都能正常运行,参数已调好,可直接运行。 内含资料,对Si

    数据结构与算法中的回文串:马拉车算法与中心扩展法的Python实现及其应用

    内容概要:本文详细介绍了关于寻找最长回文子串的相关知识,包括前置理论、不同求解方法的具体操作及其优势。首先,阐述了回文串这一特殊结构的概念及其特性——正序逆序完全一致。紧接着,围绕中心扩展法和马拉车算法展开叙述。前者基于字符逐一检查周边字符的方法,在每一点向外延伸探索最长相同序列。而后者利用预处理阶段将字符间隔用特殊符号填充形成全新字符串形式,并建立相应的辅助工具(如回文半径数组)用于跟踪回文中点位置与范围变动情况,再经由巧妙规则判定并逐步推进搜索进度,从而大大降低了运行成本。最后还提到了两种常规方法——动态规划与中心扩展的具体思路以及它们各自适用的情况和局限性。 适合人群:正在研究或学习数据结构和算法特别是字符串处理相关领域的技术人员和爱好者。 使用场景及目标:帮助开发者针对字符串匹配类的问题,尤其是回文判定和查找场景,掌握更多高效的解决方案,优化程序性能。具体应用场景如文本编辑器、搜索引擎中的关键字检索等方面可能会涉及到这类算法的应用。

    录屏软件亲测可用哦,非常好用

    录屏

    C语言实践作业飞机大战.zip

    C语言实践作业飞机大战.zip

    人机对话意图识别数据集

    人机对话意图识别数据集

    瑞幸咖啡企业微信群话术及人设搭建SOP.xlsx

    瑞幸咖啡企业微信群话术及人设搭建SOP.xlsx

    基于java的居家养老健康管理系统设计与实现.docx

    基于java的居家养老健康管理系统设计与实现.docx

    基于java的在线租房招聘平台设计与实现.docx

    基于java的在线租房招聘平台设计与实现.docx

    基于java的企业信息管理系统设计与实现.docx

    基于java的企业信息管理系统设计与实现.docx

Global site tag (gtag.js) - Google Analytics