character/byte/ coding __字符,字节和编码



摘要:本文介绍了字符与编码的发展过程,相关概念的正确理解。举例说明了一些实际应用中,编码的实现方法。然后,本文讲述了通常对字符与编码的几种误解,由于这些误解而导致乱码产生的原因,以及消除乱码的办法。本文的内容涵盖了“中文问题”,“乱码问题”。

掌握编码问题的关键是正确地理解相关概念,编码所涉及的技术其实是很简单的。因此,阅读本文时需要慢读多想,多思考。

引言

“字符与编码”是一个被经常讨论的话题。即使这样,时常出现的乱码仍然困扰着大家。虽然我们有很多的办法可以用来消除乱码,但我们并不一定理解这些办法的内在原理。而有的乱码产生的原因,实际上由于底层代码本身有问题所导致的。因此,不仅是初学者会对字符编码感到模糊,有的底层开发人员同样对字符编码缺乏准确的理解。


1. 编码问题的由来,相关概念的理解

1.1 字符与编码的发展

从计算机对多国语言的支持角度看,大致可以分为三个阶段:

  系统内码 说明 系统
阶段一 ASCII 计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示。 英文 DOS
阶段二 ANSI编码
(本地化) 为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。

不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。

不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。 中文 DOS,中文 Windows 95/98,日文 Windows 95/98
阶段三 UNICODE
(国际化) 为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。 Windows NT/2000/XP,Linux,Java
字符串在内存中的存放方法:

在 ASCII 阶段,单字节字符串使用一个字节存放一个字符(SBCS)。比如,"Bob123" 在内存中为:

42 6F 62 31 32 33 00

B o b 1 2 3 \0
在使用 ANSI 编码支持多种语言阶段,每个字符使用一个字节或多个字节来表示(MBCS),因此,这种方式存放的字符也被称作多字节字符。比如,"中文123" 在中文 Windows 95 内存中为7个字节,每个汉字占2个字节,每个英文和数字字符占1个字节:

D6 D0 CE C4 31 32 33 00

中 文 1 2 3 \0
在 UNICODE 被采用之后,计算机存放字符串时,改为存放每个字符在 UNICODE 字符集中的序号。目前计算机一般使用 2 个字节(16 位)来存放一个序号(DBCS),因此,这种方式存放的字符也被称作宽字节字符。比如,字符串 "中文123" 在 Windows 2000 下,内存中实际存放的是 5 个序号:

2D 4E 87 65 31 00 32 00 33 00 00 00      ← 在 x86 CPU 中,低字节在前

中 文 1 2 3 \0  
一共占 10 个字节。

1.2 字符,字节,字符串

理解编码的关键,是要把字符的概念和字节的概念理解准确。这两个概念容易混淆,我们在此做一下区分:

  概念描述 举例
字符 人们使用的记号,抽象意义上的一个符号。 '1', '中', 'a', '$', '¥', ……
字节 计算机中存储数据的单元,一个8位的二进制数,是一个很具体的存储空间。 0x01, 0x45, 0xFA, ……
ANSI
字符串 在内存中,如果“字符”是以 ANSI 编码形式存在的,一个字符可能使用一个字节或多个字节来表示,那么我们称这种字符串为 ANSI 字符串或者多字节字符串。 "中文123"
(占7字节)
UNICODE
字符串 在内存中,如果“字符”是以在 UNICODE 中的序号存在的,那么我们称这种字符串为 UNICODE 字符串或者宽字节字符串。 L"中文123"
(占10字节)
由于不同 ANSI 编码所规定的标准是不相同的,因此,对于一个给定的多字节字符串,我们必须知道它采用的是哪一种编码规则,才能够知道它包含了哪些“字符”。而对于 UNICODE 字符串来说,不管在什么环境下,它所代表的“字符”内容总是不变的。


1.3 字符集与编码

各个国家和地区所制定的不同 ANSI 编码标准中,都只规定了各自语言所需的“字符”。比如:汉字标准(GB2312)中没有规定韩国语字符怎样存储。这些 ANSI 编码标准所规定的内容包含两层含义:

使用哪些字符。也就是说哪些汉字,字母和符号会被收入标准中。所包含“字符”的集合就叫做“字符集”。
规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储,这个规定就叫做“编码”。
各个国家和地区在制定编码标准的时候,“字符的集合”和“编码”一般都是同时制定的。因此,平常我们所说的“字符集”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。

“UNICODE 字符集”包含了各种语言中使用到的所有“字符”。用来给 UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。

1.4 常用的编码简介

简单介绍一下常用的编码规则,为后边的章节做一个准备。在这里,我们根据编码规则的特点,把所有的编码分成三类:

分类 编码标准 说明
单字节字符编码 ISO-8859-1 最简单的编码规则,每一个字节直接作为一个 UNICODE 字符。比如,[0xD6, 0xD0] 这两个字节,通过 iso-8859-1 转化为字符串时,将直接得到 [0x00D6, 0x00D0] 两个 UNICODE 字符,即 "ÖÐ"。

反之,将 UNICODE 字符串通过 iso-8859-1 转化为字节串时,只能正常转化 0~255 范围的字符。
ANSI 编码 GB2312,
BIG5,
Shift_JIS,
ISO-8859-2 …… 把 UNICODE 字符串通过 ANSI 编码转化为“字节串”时,根据各自编码的规定,一个 UNICODE 字符可能转化成一个字节或多个字节。

反之,将字节串转化成字符串时,也可能多个字节转化成一个字符。比如,[0xD6, 0xD0] 这两个字节,通过 GB2312 转化为字符串时,将得到 [0x4E2D] 一个字符,即 '中' 字。

“ANSI 编码”的特点:
1. 这些“ANSI 编码标准”都只能处理各自语言范围之内的 UNICODE 字符。
2. “UNICODE 字符”与“转换出来的字节”之间的关系是人为规定的。
UNICODE 编码 UTF-8,
UTF-16, UnicodeBig …… 与“ANSI 编码”类似的,把字符串通过 UNICODE 编码转化成“字节串”时,一个 UNICODE 字符可能转化成一个字节或多个字节。

与“ANSI 编码”不同的是:
1. 这些“UNICODE 编码”能够处理所有的 UNICODE 字符。
2. “UNICODE 字符”与“转换出来的字节”之间是可以通过计算得到的。
我们实际上没有必要去深究每一种编码具体把某一个字符编码成了哪几个字节,我们只需要知道“编码”的概念就是把“字符”转化成“字节”就可以了。对于“UNICODE 编码”,由于它们是可以通过计算得到的,因此,在特殊的场合,我们可以去了解某一种“UNICODE 编码”是怎样的规则。

2. 字符与编码在程序中的实现

2.1 程序中的字符与字节

在 C++ 和 Java 中,用来代表“字符”和“字节”的数据类型,以及进行编码的方法:

类型或操作 C++ Java
字符 wchar_t char
字节 char byte
ANSI 字符串 char[] byte[]
UNICODE 字符串 wchar_t[] String
字节串→字符串 mbstowcs(), MultiByteToWideChar() string = new String(bytes, "encoding")
字符串→字节串 wcstombs(), WideCharToMultiByte() bytes = string.getBytes("encoding")
以上需要注意几点:

Java 中的 char 代表一个“UNICODE 字符(宽字节字符)”,而 C++ 中的 char 代表一个字节。
MultiByteToWideChar() 和 WideCharToMultiByte() 是 Windows API 函数。

2.2 C++ 中相关实现方法

声明一段字符串常量:

// ANSI 字符串,内容长度 7 字节
char     sz[20] = "中文123";

// UNICODE 字符串,内容长度 5 个 wchar_t(10 字节)
wchar_t wsz[20] = L"\x4E2D\x6587\x0031\x0032\x0033";
UNICODE 字符串的 I/O 操作,字符与字节的转换操作:

// 运行时设定当前 ANSI 编码,VC 格式
setlocale(LC_ALL, ".936");

// GCC 中格式
setlocale(LC_ALL, "zh_CN.GBK");

// Visual C++ 中使用小写 %s,按照 setlocale 指定编码输出到文件
// GCC 中使用大写 %S
fwprintf(fp, L"%s\n", wsz);

// 把 UNICODE 字符串按照 setlocale 指定的编码转换成字节
wcstombs(sz, wsz, 20);
// 把字节串按照 setlocale 指定的编码转换成 UNICODE 字符串
mbstowcs(wsz, sz, 20);
在 Visual C++ 中,UNICODE 字符串常量有更简单的表示方法。如果源程序的编码与当前默认 ANSI 编码不符,则需要使用 #pragma setlocale,告诉编译器源程序使用的编码:

// 如果源程序的编码与当前默认 ANSI 编码不一致,
// 则需要此行,编译时用来指明当前源程序使用的编码
#pragma setlocale(".936")

// UNICODE 字符串常量,内容长度 10 字节
wchar_t wsz[20] = L"中文123";
以上需要注意 #pragma setlocale 与 setlocale(LC_ALL, "") 的作用是不同的,#pragma setlocale 在编译时起作用,setlocale() 在运行时起作用。

2.3 Java 中相关实现方法

字符串类 String 中的内容是 UNICODE 字符串:

// Java 代码,直接写中文
String string = "中文123";

// 得到长度为 5,因为是 5 个字符
System.out.println(string.length());
字符串 I/O 操作,字符与字节转换操作。在 Java 包 java.io.* 中,以“Stream”结尾的类一般是用来操作“字节串”的类,以“Reader”,“Writer”结尾的类一般是用来操作“字符串”的类。

// 字符串与字节串间相互转化

// 按照 GB2312 得到字节(得到多字节字符串)
byte [] bytes = string.getBytes("GB2312");

// 从字节按照 GB2312 得到 UNICODE 字符串
string = new String(bytes, "GB2312");

// 要将 String 按照某种编码写入文本文件,有两种方法:

// 第一种办法:用 Stream 类写入已经按照指定编码转化好的字节串
OutputStream os = new FileOutputStream("1.txt");
os.write(bytes);
os.close();

// 第二种办法:构造指定编码的 Writer 来写入字符串
Writer ow = new OutputStreamWriter(new FileOutputStream("2.txt"), "GB2312");
ow.write(string);
ow.close();

/* 最后得到的 1.txt 和 2.txt 都是 7 个字节 */
如果 java 的源程序编码与当前默认 ANSI 编码不符,则在编译的时候,需要指明一下源程序的编码。比如:

E:\>javac -encoding BIG5 Hello.java
以上需要注意区分源程序的编码与 I/O 操作的编码,前者是在编译时起作用,后者是在运行时起作用。

3. 几种误解,以及乱码产生的原因和解决办法

3.1 容易产生的误解

  对编码的误解
误解一 在将“字节串”转化成“UNICODE 字符串”时,比如在读取文本文件时,或者通过网络传输文本时,容易将“字节串”简单地作为单字节字符串,采用每“一个字节”就是“一个字符”的方法进行转化。

而实际上,在非英文的环境中,应该将“字节串”作为 ANSI 字符串,采用适当的编码来得到 UNICODE 字符串,有可能“多个字节”才能得到“一个字符”。

通常,一直在英文环境下做开发的程序员们,容易有这种误解。
误解二 在 DOS,Windows 98 等非 UNICODE 环境下,字符串都是以 ANSI 编码的字节形式存在的。这种以字节形式存在的字符串,必须知道是哪种编码才能被正确地使用。这使我们形成了一个惯性思维:“字符串的编码”。

当 UNICODE 被支持后,Java 中的 String 是以字符的“序号”来存储的,不是以“某种编码的字节”来存储的,因此已经不存在“字符串的编码”这个概念了。只有在“字符串”与“字节串”转化时,或者,将一个“字节串”当成一个 ANSI 字符串时,才有编码的概念。

不少的人都有这个误解。
第一种误解,往往是导致乱码产生的原因。第二种误解,往往导致本来容易纠正的乱码问题变得更复杂。

在这里,我们可以看到,其中所讲的“误解一”,即采用每“一个字节”就是“一个字符”的转化方法,实际上也就等同于采用 iso-8859-1 进行转化。因此,我们常常使用 bytes = string.getBytes("iso-8859-1") 来进行逆向操作,得到原始的“字节串”。然后再使用正确的 ANSI 编码,比如 string = new String(bytes, "GB2312"),来得到正确的“UNICODE 字符串”。

3.2 非 UNICODE 程序在不同语言环境间移植时的乱码

非 UNICODE 程序中的字符串,都是以某种 ANSI 编码形式存在的。如果程序运行时的语言环境与开发时的语言环境不同,将会导致 ANSI 字符串的显示失败。

比如,在日文环境下开发的非 UNICODE 的日文程序界面,拿到中文环境下运行时,界面上将显示乱码。如果这个日文程序界面改为采用 UNICODE 来记录字符串,那么当在中文环境下运行时,界面上将可以显示正常的日文。

由于客观原因,有时候我们必须在中文操作系统下运行非 UNICODE 的日文软件,这时我们可以采用一些工具,比如,南极星,AppLocale 等,暂时的模拟不同的语言环境。

3.3 网页提交字符串

当页面中的表单提交字符串时,首先把字符串按照当前页面的编码,转化成字节串。然后再将每个字节转化成 "%XX" 的格式提交到 Web 服务器。比如,一个编码为 GB2312 的页面,提交 "中" 这个字符串时,提交给服务器的内容为 "%D6%D0"。

在服务器端,Web 服务器把收到的 "%D6%D0" 转化成 [0xD6, 0xD0] 两个字节,然后再根据 GB2312 编码规则得到 "中" 字。

在 Tomcat 服务器中,request.getParameter() 得到乱码时,常常是因为前面提到的“误解一”造成的。默认情况下,当提交 "%D6%D0" 给 Tomcat 服务器时,request.getParameter() 将返回 [0x00D6, 0x00D0] 两个 UNICODE 字符,而不是返回一个 "中" 字符。因此,我们需要使用 bytes = string.getBytes("iso-8859-1") 得到原始的字节串,再用 string = new String(bytes, "GB2312") 重新得到正确的字符串 "中"。
3.4 从数据库读取字符串

通过数据库客户端(比如 ODBC 或 JDBC)从数据库服务器中读取字符串时,客户端需要从服务器获知所使用的 ANSI 编码。当数据库服务器发送字节流给客户端时,客户端负责将字节流按照正确的编码转化成 UNICODE 字符串。

如果从数据库读取字符串时得到乱码,而数据库中存放的数据又是正确的,那么往往还是因为前面提到的“误解一”造成的。解决的办法还是通过 string = new String( string.getBytes("iso-8859-1"), "GB2312") 的方法,重新得到原始的字节串,再重新使用正确的编码转化成字符串。

3.5 电子邮件中的字符串

当一段 Text 或者 HTML 通过电子邮件传送时,发送的内容首先通过一种指定的字符编码转化成“字节串”,然后再把“字节串”通过一种指定的传输编码(Content-Transfer-Encoding)进行转化得到另一串“字节串”。比如,打开一封电子邮件源代码,可以看到类似的内容:

Content-Type: text/plain;
        charset="gb2312"
Content-Transfer-Encoding: base64

sbG+qcrQuqO17cf4yee74bGjz9W7+b3wudzA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0NDEDQoNCg==
最常用的 Content-Transfer-Encoding 有 Base64 和 Quoted-Printable 两种。在对二进制文件或者中文文本进行转化时,Base64 得到的“字节串”比 Quoted-Printable 更短。在对英文文本进行转化时,Quoted-Printable 得到的“字节串”比 Base64 更短。

邮件的标题,用了一种更简短的格式来标注“字符编码”和“传输编码”。比如,标题内容为 "中",则在邮件源代码中表示为:

// 正确的标题格式
Subject: =?GB2312?B?1tA=?=
其中,

第一个“=?”与“?”中间的部分指定了字符编码,在这个例子中指定的是 GB2312。
“?”与“?”中间的“B”代表 Base64。如果是“Q”则代表 Quoted-Printable。
最后“?”与“?=”之间的部分,就是经过 GB2312 转化成字节串,再经过 Base64 转化后的标题内容。
如果“传输编码”改为 Quoted-Printable,同样,如果标题内容为 "中":

// 正确的标题格式
Subject: =?GB2312?Q?=D6=D0?=
如果阅读邮件时出现乱码,一般是因为“字符编码”或“传输编码”指定有误,或者是没有指定。比如,有的发邮件组件在发送邮件时,标题 "中":

// 错误的标题格式
Subject: =?ISO-8859-1?Q?=D6=D0?=
这样的表示,实际上是明确指明了标题为 [0x00D6, 0x00D0],即 "ÖÐ",而不是 "中"。

4. 几种错误理解的纠正

误解:“ISO-8859-1 是国际编码?”

非也。iso-8859-1 只是单字节字符集中最简单的一种,也就是“字节编号”与“UNICODE 字符编号”一致的那种编码规则。当我们要把一个“字节串”转化成“字符串”,而又不知道它是哪一种 ANSI 编码时,先暂时地把“每一个字节”作为“一个字符”进行转化,不会造成信息丢失。然后再使用 bytes = string.getBytes("iso-8859-1") 的方法可恢复到原始的字节串。

误解:“Java 中,怎样知道某个字符串的内码?”

Java 中,字符串类 java.lang.String 处理的是 UNICODE 字符串,不是 ANSI 字符串。我们只需要把字符串作为“抽象的符号的串”来看待。因此不存在字符串的内码的问题。

 

原创文章,转载请保留或注明出处: http://www.regexlab.com/zh/encoding.html 


java字节流和字符流这里讲的也不错:http://liyanhui.iteye.com/blog/185580

 

Python编码声明实战:从# -*- coding: gbk -*-到现代项目的最佳实践 五年前我接手维护一个用GBK编码的Python 2项目时,遇到了各种编码问题。最典型的就是在Windows系统上运行正常的脚本,放到Linux服务器就报编码错误。在处理编码问题时,我最大的体会是:预防胜于治疗。这时候就需要在文件开头声明编码方式,告诉解释器:"别用ASCII解析了,我用的是GBK/UTF-8"。是Emacs的特定语法,Python为了兼容各种编辑器,后来也支持更简单的写法。从数据库或API获取数据时,经常会遇到编码不一致的情况。有趣的是,这个语法其实借鉴自Emacs编辑器的文件头规范。 阅读详情

相关推荐

GB2312/GBK/Unicode 3种编码对比:从区位码到UTF-8的转换链路解析

本文深入解析GB2312、GBK和Unicode三种中文编码体系的技术演进,从区位码到UTF-8的转换链路。详细介绍了GB2312的双字节编码结构、GBK的扩展改进以及Unicode的UTF-8实现,帮助开发者理解编码转换原理,解决实际开发中的乱码问题。

weixin_34416649的博客 326

字符,字节和编码

 字符,字节和编码摘要:本文介绍了字符与编码的发展过程,相关概念的正确理解。举例说明了一些实际应用中,编码的实现方法。然后,本文讲述了通常对字符与编码的几种误解,由于这些误解而导致乱码产生的原因,以及消除乱码的办法。本文的内容涵盖了“中文问题”,“乱码问题”。掌握编码问题的关键是正确地理解相关概念,编码所涉及的技术其实是很简单的。因此,阅读本文时需要慢读多想,多思考。引言“字符与编码”

博命生涯 1216

Java与Python字符串处理实战:编码、分词与业务验证全流程解析

字符串处理是编程中的基础且关键的技术环节,涉及数据在内存中的表示、传输与存储。其核心原理在于理解字符串的不可变性、字符编码(如UTF-8、GBK)以及高效操作方式(如Java的StringBuilder)。这项技术的价值在于确保数据的完整性与安全性,是构建健壮应用、处理用户输入、解析日志和实现地域化服务的基础。在实际应用中,开发者常需处理包含特定语义(如中文地名、商品名)的字符串,并从中提取有效信息进行业务验证。本文以“安徽板面”这一具体案例为切入点,系统阐述了在Java和Python环境中,如何通过编码解

congjukun0600的博客 322

String

new String(bytes,encoding)    java中的String类是按照unicode进行编码的。    encoding所指的是bytes中的数据是按照encoding那种方式编码的,而不是最后产生的String是什么编码方式,最后产生是的unicode编码。    换句话说,是让系统把bytes中的数据由encoding编码方式转换成unicode编码。如果不指明,byt...

639

乱码问题终极指南:从编码原理到实战修复,彻底告别“锟斤拷”

字符编码是计算机存储和处理文本信息的基础规则,它定义了字符与二进制数据之间的映射关系。其核心原理在于编码(将字符转换为字节)与解码(将字节还原为字符)过程的匹配。统一且正确的编码方案对于保障数据在存储、传输和显示过程中的一致性至关重要,其技术价值在于实现跨平台、跨语言的无障碍信息交换。在软件开发、数据处理和系统运维等应用场景中,编码不一致是导致乱码问题的根本原因。例如,当UTF-8编码的文本被错误地用GBK解码时,就可能产生经典的“锟斤拷”乱码;而Java应用在启动时若通过`JAVA_TOOL_OPTION

chaoyv 389

嵌入式中文短信发送:GB2312转Unicode编码与PDU模式实战

在嵌入式系统开发中,字符编码转换是处理多语言通信的基础技术。其核心原理在于将本地字符集(如GB2312)映射到国际通用的Unicode标准,确保数据在不同系统间正确解析。这项技术的工程价值在于解决了嵌入式设备(如使用GSM/GPRS模块的终端)在有限资源下实现可靠中文通信的难题。通过高效的查表算法(如二分查找)和精心设计的数据结构,开发者可以在单片机(如STM32、ESP32)上实现GB2312到Unicode的实时转换,并集成到PDU(Protocol Data Unit)短信发送流程中。典型应用场景包括

weixin_30727835的博客 357

Java 基础类型 —— String

Java String 类方法归纳解析。intern() 应用场景。Format 示例。JavaWeb 设计的编解码。常见乱码解析。

一步一步往上爬 803

避开生产计划大坑:不懂MPS和MRP的区别,你的SAP PP模块白学了

本文深入解析SAP PP模块中MPS(主生产计划)与MRP(物料需求计划)的核心区别,揭示如何通过正确配置避免生产计划中的常见陷阱。文章详细探讨了MPS的三大缓冲特性和动态平衡算法,帮助企业提升生产计划稳定性,优化资源配置,避免生产线波动。

weixin_29268267的博客 404

Java中文乱码问题的分析及其解决方案

随着全球化的发展,软件需要支持多种语言,特别是中文。然而,Java开发者经常遇到中文乱码问题,这可能会导致数据传输和显示错误。本文将深入探讨Java中文乱码的原因,并提供一系列解决方案。处理Java中文乱码问题需要细心和正确的编码知识。本文提供的解决方案可以帮助开发者避免常见的陷阱,确保软件能够正确处理中文字符。

脚踏实地,实事求是。 9687

帝国CMS v7.5存储型XSS漏洞挖掘与修复实战

存储型XSS(跨站脚本攻击)是一种常见的Web安全漏洞,其核心原理是攻击者将恶意脚本代码提交并永久存储在服务器端(如数据库),当其他用户访问包含该数据的页面时,脚本会在其浏览器中执行。这种漏洞的危害在于其持久性和广泛的影响范围,可能导致用户Cookie被窃取、会话被劫持,甚至引发蠕虫式传播。从技术价值看,理解存储型XSS有助于掌握Web应用安全的核心逻辑,即数据在输入、处理和输出全链路中的安全风险。在内容管理系统(CMS)等Web应用场景中,用户可控的输入点(如个人资料、评论、公告)若未经妥善过滤和输出编码

weixin_29327525的博客 300

Voicebox本地部署:模型下载与离线模式实战指南

在本地语音处理场景中,模型下载失败和离线运行需求是开发者最常遇到的两大难题。理解语音工具的本地推理原理,关键在于掌握模型文件与程序逻辑的分离管理:模型独立下载,程序负责推理,输出留在本机。这种架构带来显著的技术价值——数据不出本地、不依赖公网、批量任务不中断。无论是语音识别转写、语音合成,还是集成到自动化脚本中,本地离线模式都能在隐私敏感或网络不稳定环境下稳定运行。对开发者而言,先解决模型文件的完整获取,再验证离线启动流程,就能绕过“无法下载模型”的常见坑。本文从环境准备、模型放置、服务启动到接口调用,提供

weixin_29048309的博客 312

Java中文乱码浅析及解决方案

Java中文乱码问题是Java开发中常见的问题之一,尤其在处理字符串、文件读写、网络传输以及数据库操作时经常遇到。中文乱码问题主要是由于字符编码不一致所导致的。

用文字记录下每一个瞬间的感动和每一次思考的火花 10万+

交通银行金融科技后端开发实习生面试经验

笔试之路的第一个脚印。不足的地方:基本功不扎实,得补。先补sql(先整理出一篇sql语句做题的文章,争取下次笔试拿下这一块),编程题中的SQL写不出来感觉很丢人。然后补八股文,结合一些网上项目教程,来理解常用的一些八股文(比如各种锁)。

T__TSZ的博客 1739

Python新手必看:解决SyntaxError: Non-ASCII character的3种实用方法(含Python2/3差异)

本文详细解析Python中常见的SyntaxError: Non-ASCII character错误,提供3种实用解决方法,包括添加编码声明、配置编辑器使用UTF-8和使用ASCII替代方案。特别对比了Python 2和Python 3在编码处理上的关键差异,帮助开发者快速解决编码问题并写出兼容性更好的代码。

dfu65065的博客 1261

波束成形(Beamforming)详解

波束成形(Beamforming)是一种智能天线技术,通过调整天线阵列的相位和幅度,使信号在特定方向上增强,同时抑制干扰,提高通信性能。根据实现方式,可分为固定波束成形和自适应波束成形;按计算方式,则包括模拟、数字和混合波束成形。该技术在 5G/6G、毫米波通信、MIMO、车联网、卫星通信 等领域广泛应用。其关键技术包括 相控阵、预编码、波束扫描和波束跟踪。未来,结合 AI、超大规模 MIMO(XL-MIMO)和太赫兹通信,波束成形将在无线通信、智能交通、环境感知等领域发挥核心作用。

斯黄人民的博客 2393

Python爬取谷歌学术全攻略:基于Playwright与Asyncio的高效、抗反爬虫实践

同时,文章将详细解析爬虫过程中可能遇到的各种挑战,如IP封锁、验证码、动态内容加载等,并提供切实可行的解决方案。self.logger.info(f"第 {current_page} 页解析完成,共找到 {len(page_results)} 条结果。:谷歌学术的HTML结构并非一成不变,其CSS类名和标签结构可能会发生变化,且不同地区、不同语言的界面可能存在差异,增加了数据解析的难度。self.logger.info(f"开始搜索关键词: '{keyword}',计划爬取 {max_pages} 页")

2201_76125261的博客 1550

多语言字符处理全链路实践:从UTF-8编码到乱码排查

字符编码是计算机处理文本数据的基础,它定义了字符与字节序列之间的映射规则。其核心原理在于通过特定的编码方案(如UTF-8、GBK)将人类可读的字符转换为计算机可存储和传输的二进制数据。理解并正确应用字符编码对于保障软件的数据完整性与国际化能力至关重要,尤其是在处理包含中文、日文、英文等多语言混合的文本时。在实际工程中,统一采用UTF-8编码已成为行业最佳实践,它能有效避免因编码不一致导致的乱码、数据截断等问题。本文以典型的多语言混合字符串为例,系统阐述了在开发环境、数据库存储、网络传输及代码操作等全链路中配

weixin_33724570的博客 1259

如何用Python打造PubMed API客户端:科研文献检索自动化实践

PubMed提供了官方的Entrez E-utilities API接口,支持程序化检索文献,但直接调用API需处理请求重试、参数封装、数据解析等问题。批量获取文献ID及结构化详情(标题、作者、DOI等)内置重试机制,应对网络波动或API限流统一数据输出格式,便于后续分析(如文献计量、AI文本处理)灵活适配不同检索需求(如指定数据库、结果数量)本文实现的PubMed API客户端,通过封装API请求、重试机制、数据解析,让科研文献检索从“手动点击”变为“代码自动化”。

ASKCOS博客 360

Python编码错误解析:从SyntaxError到UTF-8与GBK编码原理详解

字符编码是计算机处理文本数据的基础规则,它定义了字符与二进制字节序列之间的映射关系。在编程中,常见的编码标准包括ASCII、GBK和UTF-8等,其中ASCII仅支持英文字符,GBK主要用于中文字符表示,而UTF-8作为Unicode的一种变长编码实现,能够兼容ASCII并覆盖全球所有语言字符。理解编码原理对于解决跨平台、跨语言协作中的乱码和解析错误至关重要,尤其在Python开发中,默认的UTF-8编码与历史遗留的GBK编码冲突常导致SyntaxError。本文通过分析Python解释器在词法分析阶段遇到

weixin_34387468的博客 974

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

彻底解决Python UnicodeEncodeError:从编码原理到实战解决方案

字符编码是计算机处理文本信息的基础技术,它定义了字符与二进制数据之间的映射规则。在中文环境下,GBK编码因其历史原因被广泛使用,但其字符集容量有限,无法表示Unicode标准中的所有字符,这导致了常见的编码错误。理解编码原理对于构建健壮的软件系统至关重要,它能确保数据在不同系统间传输时保持完整性和一致性。在实际开发中,尤其是在处理多源数据、Web应用构建和数据库交互时,编码问题直接影响程序的稳定性和用户体验。本文以Python中典型的UnicodeEncodeError为例,深入解析其根源,并提供从文件操作

weixin_33827731的博客 293

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

深入理解ASCII码与字符串转换:原理、实战与跨语言实现

字符编码是计算机科学的基础概念,它定义了字符与数字代码之间的映射关系。ASCII码作为最经典的字符编码标准,将128个英文字符、数字和控制符映射到0-127的数字,实现了文本在计算机中的标准化存储与传输。其技术价值在于为不同系统间的数据交换提供了通用语言,是网络通信、文件存储和硬件交互的基石。在实际工程中,开发者常需在人类可读的字符串与机器可处理的ASCII码序列之间进行双向转换,这一过程涉及编码(Encode)与解码(Decode)两个核心操作。例如,在网络协议解析或嵌入式系统通信时,需要将接收到的十六进

weixin_34345753的博客 315

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

GB2312、UTF-8、UCS-2编码对照表:解决中文乱码的终极指南

字符编码是计算机存储和处理文本的基础,它定义了字符与二进制数字之间的映射关系。其核心原理在于为每个字符分配一个唯一的数字标识(码点),不同的编码方案则决定了这些码点如何转换为字节序列进行存储和传输。理解编码原理具有极高的技术价值,它是确保数据在不同系统、平台和应用程序间正确交换与显示的关键,能从根本上解决乱码问题,保障信息的完整性与一致性。在实际应用场景中,无论是处理遗留系统的GB2312编码数据、配置现代开发环境的UTF-8支持,还是进行跨平台的数据迁移与清洗,掌握编码对应关系都是不可或缺的技能。本文聚焦

weixin_30785593的博客 408

Python UnicodeDecodeError:从原理到实战,彻底解决UTF-8解码错误

在数据处理和文本解析中,字符编码是确保信息准确交换的基础。UTF-8作为当前最通用的编码方案,其变长设计虽然高效,但也带来了解码错误的常见挑战。当程序尝试用UTF-8规则解析非UTF-8编码的字节序列时,就会触发“invalid continuation byte”这类错误,其本质是编码规则不匹配。理解UTF-8的编码原理,特别是首字节与连续字节的格式约定,是诊断问题的关键。这类问题的技术价值在于,它不仅是让程序运行,更是深入理解计算机底层文本处理机制的契机。在实际应用场景中,无论是处理来自老旧系统的数据文

weixin_30924087的博客 511

Python 文件读写编码陷阱排查:从 `UnicodeDecodeError` 到 `open()` 的 5 步解决法

本文深入解析Python文件读写中的编码问题,特别是常见的`UnicodeDecodeError`错误,提供从诊断到解决的完整方案。通过五步排查法、智能编码处理工具链和预防体系,帮助开发者彻底解决`gbk`等字符编码问题,确保文件操作的高效与准确。

defkaug153461的博客 327
上一篇: 假如突然间失明了会怎样呢?
下一篇: IO_FileInput(Output)Stream【009】
java_cto
博客等级 码龄18年 5粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值