我对字符编码的概念很困惑。
什么是Unicode、GBK等?编程语言如何使用它们?
我需要费心去了解他们吗?有没有一种更简单或更快的编程方法,而不必麻烦自己?
字符编码是用来解决为使用不同语言的人编写软件的问题。
你不知道这些字符是什么,它们是如何排列的。因此,您不知道这种新语言中的字符串在二进制中是什么样子,坦率地说,您不在乎。
你所拥有的是一种将字符串从你所说的语言翻译成他们所说的语言的方法(比如翻译)。您现在需要一个能够以二进制表示两种语言而不冲突的系统。编码就是那个系统。
它允许您编写工作的软件,而不管语言用二进制表示的方式如何。
最初,1个字符始终存储为1字节。一个字节(8位)有可能区分256个可能的值。但实际上只使用了前7位。所以只定义了128个字符。此集合称为ASCII字符集。
0x00
-0x1F
包含转向码(例如。CR, LF, STX, ETX, EOT, BEL,...) 0x20
-0x40
包含数字和标点符号0x41
-0x7F
包含大部分字母字符0x80
-0xFF
第8位=未定义。法语、德语和许多其他语言需要额外的字符。(例如à、é、ç、ô、...
),而ASCII字符集中没有这些字符。所以他们用第8位来定义他们的角色。这就是所谓的“扩展ASCII”。
问题是,额外的1位容量不足以覆盖世界上所有语言。因此,每个区域都有自己的ASCII变量。有许多扩展ASCII编码(latin-1
是一种非常流行的编码)。
流行问题:“ASCII是字符集还是编码”<代码>ASCII是一个字符集。然而,在编程中,charset
和encoding
被广泛用作同义词。如果我想引用一种只包含ASCII字符的编码(第8位总是0):那就是US-ASCII
。
Unicode是字符集的一个很好的例子,而不是编码。它使用与ASCII标准相同的字符,但它使用附加字符扩展列表,从而为每个字符提供一个格式为uxxxx
的代码点。它希望包含全世界使用的所有字符(和流行图标)。
UTF-8、UTF-16和UTF-32是应用Unicode字符表的编码。但是他们每个人对如何编码都有稍微不同的方法。UTF-8在编码ASCII字符时仅使用1个字节,输出与任何其他ASCII编码相同。但是对于其他字符,它将使用第一位来指示第二个字节将跟随。
GBK是一种编码,就像UTF-8使用多个字节一样。原理基本相同。第一个字节遵循ASCII标准,因此只使用7位。但是就像UTF-8一样,第8位可以用来指示第二个字节的存在,然后用来编码22000个中文字符中的一个。主要的区别是,它不遵循Unicode字符集,相反,它使用一些中文字符集。
当您对数据进行编码时,您使用了编码,但当您解码数据时,您需要知道使用了什么编码,并使用相同的编码对其进行解码。
不幸的是,编码并不总是声明或指定的。如果所有文件都包含一个前缀来指示它们的数据存储在什么编码中,那将是理想的。但是在许多情况下,应用程序仍然必须假设或猜测他们应该使用什么编码。(例如,他们使用操作系统的标准编码)。
人们对此仍然缺乏认识,因为许多开发人员甚至不知道什么是编码。
Mime类型有时与编码混淆。它们是接收器识别到达的数据类型的有用方法。下面是HTTP协议如何使用mime类型声明定义其内容类型的示例。
Content-Type: text/html; charset=utf-8
这是另一个令人困惑的原因。mime类型描述消息包含的数据类型(例如,text/xml
,image/png
,…)。在某些情况下,还将描述数据的编码方式(即charset=utf-8
)。两个混淆点:
charset=utf-8
增加了语义混乱,因为如前所述,utf-8是一种编码而不是字符集。但正如前面所解释的,有些人只是交替使用这两个词
例如,在text/xml
的情况下,声明编码是毫无意义的(而charset
参数将被忽略)。相反,XML解析器通常会读取文件的第一行,查找
发送电子邮件时也存在同样的问题。电子邮件可以包含html消息或纯文本。在这种情况下,mime类型也用于定义内容的类型。
但是总而言之,哑剧类型并不总是足以解决问题。
在Java(和许多其他编程语言)的情况下,除了编码的危险之外,还存在将字节和整数转换为字符的复杂性,因为它们的内容存储在不同的范围内。
字节存储为带符号字节(范围:-128
到127
)
java中的char
类型存储在2个无符号字节中(范围:0
-65535
)
- 流返回范围为
-1
到255
的整数
如果您知道您的数据只包含ASCII值。然后,通过适当的技巧,您可以将数据从字节解析为字符,或者立即将它们包装成字符串。
// the -1 indicates that there is no data
int input = stream.read();
if (input == -1) throw new EOFException();
// bytes must be made positive first.
byte myByte = (byte) input;
int unsignedInteger = myByte & 0xFF;
char ascii = (char)(unsignedInteger);
java中的快捷方式是使用读取器和编写器,并在实例化它们时指定编码。
// wrap your stream in a reader.
// specify the encoding
// The reader will decode the data for you
Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
正如前面对XML文件所解释的,这并不重要,因为任何合适的DOM或JAXB封送器都会检查编码属性。
(请注意,我使用这些术语中的一些是松散的/口语化的,以获得一个更简单的解释,但仍然触及要点。)
一个字节只能有256个不同的值,即8位。
由于字符集中有超过256个字符,一般不能简单地说每个字符是一个字节。
因此,必须有描述如何将字符集中的每个字符转换为字节序列的映射。某些字符可能映射到单个字节,但其他字符必须映射到多个字节。
这些映射是编码,因为它们告诉您如何将字符编码为字节序列。
至于Unicode,在非常高的级别上,Unicode是一种尝试,为每个字符分配一个唯一的数字。显然,这个数字必须比一个字节宽一些,因为有256个以上的字符:)Java使用Unicode版本,其中每个字符都被分配一个16位的值(这就是为什么Java字符是16位宽的,并且具有从0到65535的整数值)。当您获得Java字符的字节表示时,您必须告诉JVM您要使用的编码,以便它知道如何为该字符选择字节序列。
我的目标是从一个项目中创建一个原型。 当我运行一个不涉及maven原型插件的目标时,我看不到任何警告: 另一方面,当我运行archetype:createfromproject时,我得到了几个: 我知道标准的maven方法是使用属性。为了解决这个问题,我试图向pom添加更多的属性,但没有一个有效。 有什么想法吗?谢谢 我有下面的pom。xml:
问题内容: 这段代码使我凝视了几分钟: 我以前从未见过,而且我也不知道Java有一个“ loop”关键字(NetBeans甚至没有像关键字一样给它上色),并且它在JDK 6中可以很好地编译。 有什么解释? 问题答案: 这不是一个。 用法:
问题内容: 我实际上对Java中字符串的编码感到困惑。我有一些问题。如果您知道答案,请帮助我: 1)内存中Java字符串的本地编码是什么?当我以哪种格式书写时,它将被存储?由于Java与机器无关,因此我认为系统不会进行编码。 2)我在网上读到“ UTF-16”是默认编码,但我感到困惑,因为我写的时候说我得到了ASCII表中的字符编号。那么ASCII和UTF-16是否相同? 3)另外,我不确定字符串
问题内容: 我正在尝试使用此命令安装Python软件包 我收到权限错误,不确定为什么。我可以使用来运行它,但是有人告诉我这是个坏主意,我应该改用virtualenv。 什么是虚拟环境?它对我有什么作用? 问题答案: 与系统Python和库一起运行会将您限制为OS提供商选择的一个特定Python版本。试图在一个Python安装上运行所有Python应用程序,可能会导致库集合之间发生版本冲突。对系统P
问题内容: 为什么要编译Python脚本?您可以直接从.py文件运行它们,并且效果很好,那么在性能上有什么优势吗? 我还注意到,我的应用程序中的某些文件被编译为.pyc,而另一些则没有,为什么? 问题答案: 它被编译为字节码,可以更快,更快速地使用。 无法编译某些文件的原因是,每次运行脚本时都会重新编译与之一起调用的主脚本。所有导入的脚本将被编译并存储在磁盘上。 Ben Blank的 重要补充:
Bootstrapping(引导) 是 Netty 中配置程序的过程,当你需要连接客户端或服务器绑定指定端口时需要使用 Bootstrapping。 如前面所述,Bootstrapping 有两种类型,一种是用于客户端的Bootstrap,一种是用于服务端的ServerBootstrap。不管程序使用哪种协议,无论是创建一个客户端还是服务器都需要使用“引导”。 面向连接 vs. 无连接 请记住,这