字符集与字符编码问题

字符集合字符编码的问题一直都在用,但是从来没有详细的了解,一下是从网络搜集到的一些资料。

 

http://drift-ice.iteye.com/blog/726265

 

http://www.iteye.com/topic/804737

 

 

http://www.iteye.com/topic/317895 写道
编码是编码字符集和字符编码方案的一个组合 ,它可以将字符集中的字符映射成字节序列。编码隐含着编码字符集和字符编码方案,从而也隐含着字符集。例如UTF-8是一种编码,它是Unicode编码字符集和UTF8编码方案的一个组合。GB2312也是一种编码,它的编码字符集就是编码的简体中文字符集,编码方案采用定长编码。实践中经常混用编码字符集和编码这两个概念,这是因为大多数编码字符集都只有一种编码方案,这样的编码字符集(或者说编码)包括GB2312, GBK, ASCII, ISO8859-1等。但是当编码字符集存在多种编码方案时,就有必要区分编码字符集和编码了,例如我们说Unicode时一般是指编码字符集,说UTF-8,UTF-16时才是指编码。

 http://drift-ice.iteye.com/blog/726265 写道

基础知识

字节和字符
字节(octet):顾其英文名而思义,就是一个八位的存储单元,取值范围一定是0~255;
字符(character):就是一个语言上的符号,"中"字就是一个字符。字符所占的大小由其编码方式解决,比如"中"在UTF-8中占3个字节(0xE4A8AD),而在GBK中,则占两个字节(0xD6D0)。

字符集和编码
字符集:字符的集合,像Unicode字符集,目标就是收纳了这个世界上所有语言的文字、符号等;
字符编码:注意,字符集只是规定了有哪些字符,而最终决定采用哪些字符,每一个字符用多个字节表示等问题,则是由编码来决定的。像Unicode字符集的编码方式有很多,诸如UTF-8、UFT-16、UTF-32等。
字符集和字符编码是分开的概念,但有时候称呼上会有些模糊,我们经常笼统地称这些Unicode字符集的编码为Unicode编码。

内码
内码:操作系统内部的字符编码。像早期的DOS采用的是ASCII,而现在的操作系统大把采用Unicode编码。

编码简史

在讲各种编码之前,有必要先讲一个编码这个令人头疼的家伙的历史,这样有助于大家理解今天的编码世界为什么会是这样一个局面。
计算机对多语言的支持,大致为分以下三个阶段。
阶段一:ASCII时代。计算机是DOS时代的计算内码是ASCII码,ASCII的表示范围就是0到127那几个符号,这意味着,DOS时代的计算机只能显示英文,而无法支持其他语言。没办法,由于英文系国家开创了并继续主导了计算机的世界,他们自然而然地认为全世界的文字用8位表示足矣。
阶段二:ANSI时代。由于上述原因,像我们这些非英文系的国家的为了显示自家的文字,不得不一开始就得面对字符编码的问题,不同国家不同地区都创建了自己的编码标准。像是中国大陆是GB2312及后来的GBK,台湾是BIG5,日本是JIS。ASCII字符集,以及这些由此派生并兼容的字符集称为ANSI字符集。
阶段三:Unicode时代。为了和谐而出现,相较于以上两个阶段,这个时代称为国际化时代,适应了跨平台,跨语言之间交换信息的需求。

 

java中汉字字符串再获取字节编码时的问题参见:http://maimode.iteye.com/admin/blogs/1341354

 

一下摘自:http://www.iteye.com/topic/311583

Java与Unicode:

 

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

 

Java的字符串是unicode编码的。

 

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

 

Java支持哪些字符集:

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

Java代码   收藏代码
  1. assertEquals("GB18030", streamReader.getEncoding());  

 

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

 

Java代码   收藏代码
  1. char[] chars = new char[is.available()];  
  2. streamReader.read(chars, 0, is.available());  
 

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

 

Java代码   收藏代码
  1. InputStream is = new FileInputStream("res/input2.data");  
  2. InputStreamReader streamReader = new InputStreamReader(is);  

 

这时候InputStreamReader采用什么编码方式读取外部资源呢?Unicode?不是,这时候采用的编码方式是JVM的默认字符集,这个默认字符集在虚拟机启动时决定,通常根据语言环境和底层操作系统的 charset 来确定。可以通过以下方式得到JVM的默认字符集:

 

Java代码   收藏代码
  1. Charset.defaultCharset();  
 

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

 

好吧,那么我通过我的IDE Ideas创建了一个文件,并以JVM默认的编码方式从这个文件读取数据,但读出来的数据竟然是乱码。为何?呵呵,其实是因为通过Ideas创建的文件是以utf-8编码的。要得到一个JVM默认编码的文件,通过手工创建一个txt文件试试吧。

 

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

 

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

 

Java代码   收藏代码
  1. "string".getBytes();  

 

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

 

Java代码   收藏代码
  1. "string".getBytes(Charset.defaultCharset());  

 

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

 

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

 

Java代码   收藏代码
  1. new String("string".getBytes());  

 

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

 

 

字符串编码迷思:

 

Java代码   收藏代码
  1. 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平台默认字符集和外部资源的编码。

 

计算机系列:字符集与字符编码(理解ASCII、ANSI、UTF-8、Unicode,解决各种乱码问题) 字符集与字符编码(理解ASCII、ANSI、UTF-8、Unicode,解决各种乱码问题) 阅读详情

相关推荐

拯救者Y9000P 2022双系统实战:Ubuntu22.04分区优化与驱动避坑指南

本文提供联想拯救者Y9000P 2022款安装Ubuntu 22.04双系统的详细实战指南。重点讲解针对该机型的磁盘分区优化方案、NVIDIA显卡驱动安装避坑技巧,以及安装后的网络、时间同步等必备配置,帮助用户高效完成双系统部署并提升使用体验。

weixin_29208327的博客 423

字符?字符集?字符编码?ascii?GB2312?UTF8?UTF16?UTF32……,剖析那些让人头痛的字符问题

很长一段时间,对于字符集和字符编码都是处于一种懵懵懂懂的状态,对于什么ascii、GB2312、UTF8、UTF16、UTF32、Unicode之类的更是绕的晕晕乎乎,从来没有正面去彻底搞清楚其中就里。 今天就在这里把这些乱七八糟的玩意彻底搞明白。 字符: 什么是字符?“我”就是一个字符,“你”也是一个字符,“他”也是一个字符。字符就是你在计算机屏幕之上看到的每一个单独的文字或符号,无关语言...

Learn_change_myself的博客 399

Stable Diffusion跑图总爆显存?别急着换显卡,试试这个PYTORCH_CUDA_ALLOC_CONF参数调优

本文深入解析了Stable Diffusion运行中常见的显存不足问题,特别是由显存碎片化导致的假性OOM现象。通过详细讲解PYTORCH_CUDA_ALLOC_CONF参数中的max_split_size_mb设置技巧,提供了一套完整的显存优化方案,帮助用户在无需升级硬件的情况下显著提升AI绘画的稳定性与效率。

weixin_42524100的博客 347

字符编码

字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整

hugh 的博客 356

Verilog中generate for循环的5个实战技巧(附完整代码示例)

本文详细介绍了Verilog中generate for循环的5个高级实战技巧,包括参数化模块实例化、条件化生成、多维硬件结构实现等,并附有完整代码示例。这些技巧能显著提升FPGA开发效率,特别适合中级Verilog开发者学习应用。

weixin_28725949的博客 187

BAPI_REPMANCONF1_CREATE_MTS实战:从MFBF事务码到精准零件反冲的代码级解析

本文深入解析了如何通过BAPI_REPMANCONF1_CREATE_MTS函数实现SAP生产模块中的零件反冲自动化。文章对比了MFBF事务码的手动操作与BAPI编程的优劣,详细拆解了函数的核心参数、数据结构、调用流程及事务控制,并提供了从数据准备到凭证获取的完整代码示例与避坑指南,帮助开发者实现高效、精准的批量投料过账。

weixin_29240343的博客 190

字符编码的知识(二)

3.伟大的创想Unicode ——不得不单独说Unicode 像天朝一样,当计算机传到世界各个国家时,为了适合当地语言和字符,设计和实现类似GB232/GBK/GB18030/BIG5的编码方案。这样各搞一套,在本地使用没有问题,一旦出现在网络中,由于不兼容,互相访问就出现了乱码现象。 为了解决这个问题,一个伟大的创想产生了——Unicode。Unicode编码...

weixin_34130269的博客 368

中国银行信息科技岗位笔试

收到笔试只剩四天了,收集的资料,后续会更新

weixin_46050242的博客 4592

建议收藏,彻底搞懂字符编码问题,从此告别中文乱码

在中文的语言环境里,身为程序员的我们一定会遇到过中文乱码的情况,究其原因就是字符编码的问题。在没有深入理解其原理之前,会觉得中文编码问题比较谜,莫名其妙地乱码,又稀里糊涂地好了。字符编码...

xmt1139057136的专栏 1999

【GameFramework框架内置模块】8、文件系统(File System)

最近好忙,鸽了好久。不能颓废了,继续发力。今天分享的是GF框架的文件系统。首先,引用比较官方的说法:GF的FileSystem虚拟文件系统,使用类似磁盘存储的感念对零散的文件进行集中管理,优化资源加载时产生的内存分配,也可以对资源进行局部片段加载,极大的提升了资源加载的性能。通俗点讲就是,我这个模块就是加载磁盘文件的,优化加载时产生的内存分配。那么,它是怎么优化的呢?

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 2452

2025年09月中国电子学会青少年软件编程(Python)等级考试试卷(三级)答案 + 解析

2025年09月中国电子学会青少年软件编程(Python)等级考试试卷(三级)答案 + 解析

伶俐角少儿编程 515

字符集

字符集为什么需要字符集为什么有各种各样的字符集标准功能快捷键为什么会发生乱码?如何将乱码后的字符串还原成它本来的样子第1步 编码第2步 解码几个常见名词的介绍ASCII码表UnicodeUTF-8总结 为什么需要字符集 我们在计算机屏幕上看到的是实体化的文字,而在计算机存储介质中存放的实际是二进制的比特(byte)流。简单来说字符集就规定了某个文字对应的二进制数值存放方式(编码)和某串二进制数值代表了哪个文字(解码)的转换关系。正因为字符和字节之间有着这种固定的对应关系,所以我们的文件在以相同的字符集传递的

lupin8的博客 308

Python爬虫实战 | 拼多多商品评论采集与深度分析

本文从 API 调用、网页渲染到情感分析与关键词提取,全流程剖析了“拼多多商品评论采集与分析”项目。Scrapy + API 可快速抓取评论;Playwright 可突破 API 限制,抓取完整页面内容;数据清洗 + 分析揭示用户真实反馈;可持续部署、扩展至更多商品 & 时间段;

2201_76125261的博客 1696

字符集与字符编码(理解ASCII、ANSI、UTF-8、Unicode,解决各种乱码问题)

在当前的软件开发中经常面临跨操作系统、跨平台、跨区域、跨语言的字符乱码问题,面对多种字符集及其编码标准共存的背景下,对现存较为流行的ASCII、ANSI、UTF-8、Unicode等名词概念与方法进行纠正和梳理,有助于理解文本在计算机中的数据表示本质,帮助解决开发中遇到的多种字符乱码问题。分析了多字符集及编码共存的原因,从字符集和字符的编码两个部分分别对ASCII、ANSI、汉字GB系列、Unicode的相关内容进行了梳理,最后在Editplus文本编辑器中进行了验证。

iamjixiaoyu的博客 7818

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

字符集与字符编码学习笔记+CPPQT开发中字符串转化乱码问题

文章摘要: 本文探讨了Qt开发中遇到的字符串乱码问题及其解决方案。当代码移植到不同主机时,由于Qt默认使用Unicode编码而Windows系统采用GBK系列编码,导致中文字符显示异常。通过将QString::fromStdString()替换为QString::fromLocal8Bit()实现编码转换,解决了乱码问题。文中还系统梳理了字符集与编码的核心概念:字符集定义字符集合(如ASCII、Unicode),编码则决定存储规则(如UTF-8、GBK)。重点解析了Unicode与UTF-8的关系,指出UT

菜一头包的博客 934

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

字符集与字符编码

多个字符,而1个字节只能存储256种字符,是远远不够的,这就导致了新的字符集与新的字符编码方式产生,一个字符可能需要1个字节,2个字节,甚至3个字节来存储,而计算机无法自动识别二进制该用那种方式读取,这就导致了同样的文件,同样的计算机在不同国家打开,会出现完全错乱的情况,也就是我们常看到的乱码。到了亚洲,就更加复杂了,亚洲国家的语言文字非常复杂,比如中文,日文,韩文,泰文,越南文,藏文,蒙文,维吾尔文等等,这些语言文字的字符集都是非常庞大的,而且完全不同的。

qq_31870737的博客 1617

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

字符编码和字符集

讲一个小故事:话说计算机是由美国佬搞出来的嘛,他们觉得一个字节(可以表示256个编码)表示英语世界里所有的字母、数字和常用特殊符号已经绰绰有余了(其实ASCII只用了前127个编码)。后来欧洲人不干了,法国人说:我需要在小写字母加上变音符号(如:é),德国人说:我也要加几个字母(Ä ä、Ö ö、Ü ü、ß)。于是,欧洲人就将ASCII没用完的编码(128-255)为自己特有的符号编码(后来称之为“扩展字符集”)。等到我们中国人开始使用计算机的时候,尼玛,256个编码哪够?

weixin_40332490的博客 942

扫盲:字符编码与字符集的区别(2010年10月9日修改)

近来学习字符编码,发现网络上总是把“字符集(Character Set)”与“字符编码(Encode)”搞混了,我也给弄得晕头转向。   其实字符编码与字符集在本质上就是不同的东西。   字符(Character)>     一个文字就是一个字符。在计算机中,字符是用数字来表示的,不同的文字用不同的数字表示。   字符集(Character Set)     既然是“集”,也就是“集合”

xinxiangsui2008的专栏 577

字符乱码之字符集和字符编码

最近经常会碰到上传客户提供的历史数据上传时csv文件用Excel打开时会有乱码问题,虽然知道知道是字符编码不一致导致的,但其中诸多细节却知之甚少,今日特来理理。 1.为什么会有字符乱码问题?如何解决字符乱码问题 计算机中存储的信息都是二进制数表示的,但是世界上有各种不同的语言文字,所以我们需要一些规则将各种字符转换成二进制后存储在计算机中 即编码,以及如果将存储在计算机中的二进制数解析出来即解...

weixin_33964094的博客 346

十分钟搞清字符集和字符编码

什么是字符集 什么是字符编码 UTF-8和Unicode的关系 UTF-8编码简介 为什么会出现乱码 如何识别乱码的本来想要表达的文字 常见问题处理之Emoji 本文将简述字符集,字符编码的概念。以及在遭遇乱码时的一些常用诊断技巧 背景:字符集和编码无疑是IT菜鸟甚至是各种大神的头痛问题。当遇到纷繁复杂的字符集,各种火星文和乱码时,问题的定位往往变得非常困难。本文就

轻锋的专栏 3153

mysql字符集设置

字符(Character)是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。在计算机中所看到的任何内容都是字符构成的。字符编码(character code)是计算机针对各种符号,在计算机中的一种二进制存储代号。字符集(Character set)是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同。常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、 GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能

woahxy的博客 1263

镭速大文件传输软件如何处理字符编码问题

在计算机的世界里,所有的信息,包括文本、图片、视频等,最终都是以0和1的二进制形式存储在硬件中的。即便是我们日常使用的字符,也不例外。那么,计算机是如何从这些看似杂乱无章的0和1中识别出我们熟悉的字母和符号呢?这就涉及到了编码和解码的过程。

doulongyun的博客 808

java语言使用的字符码集是_Java应用开发中的字符集与字符编码

事出有因在向HttpURLConnection的输出流写入内容时,因没有设置charset,导致接收方对数据的验签不一致。URL url = newURL(requestUrl);//打开连接HttpURLConnection urlConn =(HttpURLConnection)url.openConnection();............//获取输出流out = newOutputStr...

weixin_39940957的博客 2035

【python】字符编码和字符集,结合python语言示例

字符编码和字符集,结合python语言

qq_41604569的博客 585

字符集和字符编码(Charset & Encoding)

字符集和字符编码 —— 每个软件开发人员应该无条件掌握的知识! 相信大家一定碰到过,打开某个网页,却显示一堆像乱码?还记得HTTP中的Accept-Charset、Accept-Encoding、Accept-Language、Content-Encoding、Content-Language等消息头字段?这些就是接下来我们要探讨的。 1.基础知识 计算机中储存的信息都是用二进制数表示的;而我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果。通俗的说,按照何种规则将字符存储在计算机中,如’a’

alokka的博客 1115
上一篇: java中char与汉字占用字节个数问题
下一篇: NIO 编程示例代码
maimode
博客等级 码龄19年 11粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值