现代计算机采用的都是冯.诺依曼体系结构,因此都具有相同的结构特征,拥有五大组成部分:输入数据和程序的输入设备,记忆程序和数据的存储器,完成数据加工处理的运算器,控制程序执行的控制器,输出处理结果的输出设备。JVM是一台虚拟的计算机,也有类似的特征。本系列文章研究的是java中文问题,跟输入输出有着密切的联系,为了突出重点,我们暂且将JVM的其它细节放下,只需了解JVM内部的数据是用Unicode表示的,使用的编码方式是UTF-16(至于是UTF-16LE还是UTF-16BE就要看具体的虚拟机实现了,intel x86 -windows 下是UTF-16LE,这可以使用 System.getProperty("sun.io.unicode.encoding") 取得)。
现在我们具体来看运行一个控制台程序所经历的步骤以及这个过程中涉及到输入和输出。一个程序从源代码到运行大概会经历这么一个过程:
1、使用一个文本编辑器编写java源代码,完毕后保存到一个.java文件中。如果指定文件的保存格式(GBK,UTF-8 ect.),则用指定的格式保存,否则使用默认编码方式保存(记事本,Editplus,eclipse等都是使用系统默认的编码方式GBK)。
2、使用javac命令编译.java源文件,产生.class文件,以UTF-8格式保存。注意,.class文件的格式必须是UTF-8,不需要指定,也不管系统默认的编码方式是什么。
3、使用java程序,运行jvm,载入编译好的.class文件,程序开始运行。
4、运行过程中,程序从输入(标准输入,文件,网络)中取得数据,进行相应的编码转换后放进JVM,以供运算使用。运算完毕后,将产生的数据进行编码转换后输出到指定位置(标准输出,文件,网络)
这样,程序就一直运行下去,直到结束。这期间,哪些地方有可能出现中文问题呢?下面一一道来:
1、使用javac进行编译时。如果我们.java源文件保存的编码方式跟javac指定的读入编码方式不一致,则会出现中文问题。譬如,我们在中文windows环境下用eclipse编写好源文件,然后到一个英文linux环境下进行编译,如果javac时没有指定编码方式为GBK,那么javac就会按照当前系统的默认编码方式(ISO-8859-1)进行解析,虽然里面的英文字符是不会出错的,但是中文就全部变成乱码了,也就是说,javac产生的.class文件中存储的中文字符是错误的。这样,运行的时候肯定也就出问题了。
建议 1 :保存.java源文件时使用UTF-8进行保存,在使用javac编译的时候通过参数 -encoding UTF-8指定编码方式。这样,可以保证源程序在任何支持UTF-8的平台上都能通过编译。PS:通过记事本的另存为将一个源文件保存成UTF-8时,会在文件头部加上一个BOM(ef bb bf),javac会报错。但是用Editplus(从Doucument菜单中选择Permanet Settings,有三个分类,分别是General,File,Tools.点击File,右边会有一项是 UTF-8 signature: 选择 always remove signature. 点击OK),eclipse却不会出现这种问题。
2、控制台跟操作系统密切相关,标准输入输出的编码都是固定的,也就是系统的默认编码,这是不能动态改变的。如果你程序里有中文编码,在中文环境下调用System.out.println("汉"); jvm会自动将输出流转换为GBK字节串交给控制台,控制台使用默认编码就正确输出了。但是该语句在英文环境下运行的话,那里的默认编码是ISO-8859-1,jvm就将“汉”转换成相应编码交给控制台,也就是两个“?”了。
建议 2:如果程序要跨平台的话,程序里用到控制台输出的代码最好不用中文字符。
3、如果数据来自网络或者文件的话,数据源的编码方式可以多种多样。因此,我们在读入的时候一定要清楚数据源的编码方式,通知jvm进行正确的处理,否则也会出现中文问题。下面以文件读写为例。
java 中处理字符的读写一般使用FileReader和FileWriter。但是这两个类都是使用系统默认的字符编码进行文件的读写,而且不能更改处理时的编码方式。也就是说,在GBK平台只能处理GBK的文件,在ISO-8859-1的平台只能处理ISO-8859-1的文件,这当然是不能接受的。因此,使用InputStreamReader 和 OutputStreamWriter吧。只要你能保证数据源的编码方式,然后读写时配置好相应的读写器的编码方式,就不会出现中文问题了。
建议 3 :使用文件进行数据交换时,最好统一文件的编码方式,如UTF-8。虽然对于中文来说,体积会增大50%,但是换来的是很好的跨平台特性。xml就是一个很好的例子。
如果能很好地做到上面几条,那么对于一个控制台应用程序来说应该是可以避免中文问题了。
分享到:
相关推荐
### C#深入浅出全接触 #### 一、什么是C#? C# 是由微软公司开发的一种现代化的、面向对象的编程语言。它基于 C 和 C++ 的语法基础,但结合了 VB.NET 的易用性,使其既强大又易于学习。C# 的设计初衷是为了更好地...
根据提供的信息,我们可以总结并扩展出以下几个与C#相关的知识点: ### C# 语言简介 C#(发音为“C sharp”)是由微软开发的一种面向对象的编程语言,旨在为软件开发者提供一种现代、通用且面向对象的语言。C# ...
### C# 深入浅出全接触 #### 一、C# 的概念与起源 C# 是一种由微软公司研发的现代化编程语言,它基于 C 和 C++ 的语法基础,融合了现代软件工程的最佳实践和技术特点。由于 C# 是微软的产品,它不仅拥有 C++ 的...
通过深入研究这些文件和目录,以及参考《Eclipse RCP 深入浅出》一书,你将能够逐步掌握如何使用Eclipse RCP构建复杂的桌面应用程序。记得实践是掌握技术的关键,尝试运行和修改这些源码,观察结果,将理论知识转化...
### C# 深入浅出全接触 #### 一、C# 的定义与起源 C# 是一种由微软公司研发的现代化编程语言,它基于 C 和 C++ 的语法基础,融合了 Java 和 Delphi 的一些特性。C# 的设计初衷是为了提供一个既强大又易于使用的...
### C#sharp深入浅出全接触 #### 一、什么是C#? C#是由微软公司开发的一种现代化的、面向对象的编程语言。它基于C和C++语言的基础之上进行了改进和创新,使得开发者能够轻松地编写高效、稳定的应用程序。C#结合了...
### C# 深入浅出全接触 #### 一、C#简介 C#(发音为 C Sharp)是由微软公司开发的一种现代化的面向对象的编程语言,它结合了多种编程语言的优势,如C和C++的强大功能以及Visual Basic的易用性。C#旨在简化程序员的...
【JBoss教程及深入浅出JBoss+Seam】是一个针对企业级Java应用服务器JBoss的深度学习资源,其中包含了两个主要部分:JBoss教程和对JBoss与Seam框架结合使用的详细介绍。这两个主题都是Java开发人员在部署和管理企业...
### C#深入浅出——入门者先看 #### 一、C#简介 C#(发音为“C sharp”)是一种由微软公司开发的面向对象的编程语言,它结合了C和C++的强大功能,同时也拥有类似Visual Basic的易用性。C#的设计初衷是为了更好地...
《深入浅出Google+Android》是一本专门为Android开发新手量身打造的教程,旨在帮助读者从零基础开始,逐步掌握Android应用开发的核心技术。书中的内容涵盖了Google与Android的紧密关系,以及如何利用Google的相关...
【深入浅出jbpm系统开发】是一本专为jbpm工作流引擎初学者设计的入门指南,旨在帮助读者快速理解和掌握这一强大的开源工作流引擎。jbpm作为一个流行且功能丰富的工具,广泛应用于企业流程自动化、任务管理和决策支持...
### C#:深入浅出全接触 #### 一、什么是C#? C#是一种由微软公司开发的现代编程语言,其设计灵感源自C和C++,因此继承了这两种语言的强大功能,同时也融入了Visual Basic的易用性。C#特别为.NET框架而生,旨在...
### C#深入浅出知识点概览 #### 一、什么是C#? - **定义**: C#(发音为“C Sharp”)是由微软公司开发的一种现代编程语言,它结合了C和C++的强大功能以及Visual Basic的简洁性。 - **特点**: - 作为一种面向对象...
在Java编程语言中,Console User Interface (CUI) 或 Command Line Interface 应用程序通常用于简单任务,但随着用户对图形界面的需求增加,开发者需要关注应用程序的外观和用户体验。Java Swing 和 JavaFX 提供了...
《Thinking in Java》是Bruce Eckel的经典Java编程教材,它深入浅出地讲解了Java语言的核心概念和技术。这里提到的"thinking java 3 source code (chapter 2,3)"是该书第三版的第二章和第三章的源代码。下面我们将...
- 在传统的服务器程序如 Java 和 PHP 中,每个客户端连接都会创建一个新的线程来处理,这导致了大量内存消耗和线程管理开销。当并发连接数量增加时,服务器资源会被迅速耗尽,限制了系统的可扩展性。 2. **Node.js...
这篇教程将深入浅出地介绍如何使用log4j进行日志记录。 首先,log4j是一个开源的日志记录工具,由Apache软件基金会开发,主要服务于Java应用程序。它的核心组件包括Logger(日志器)、Appender(输出端)和Layout...