java编码原理,java编码和解码问题
java的编码方式原理
java的JVM的缺省编码方式由系统的“本地语言环境”设置确定,和操作系统的类型无关 。
在JAVA源文件-->JAVAC-->Class-->Java-->getBytes()-->new String()-->显示的过程中,每一步都有编码的转换过程,这个过程总是存在的,只是有的时候用默认的参数进行。
JAVAC是以系统默认编码读入源文件,然后按UNICODE进行编码的。如果没有指定编码格式而是以系统默认的编码格式进行读入文件操作,但是文件格式和系统默认编码不一致,就会在编译时出现乱码现象。
在myeclipse中,javac可以根据文件的类型,由myeclipse来确认编码的类型,来读入源文件,这样就可以智能化的读入,而不需要进行转码等操作。然后按UNICODE进行编码的。
-------------------------------
在运行过程中,JAVA也是采用UNICODE编码的,并且默认输入和输出的都是操作系统的默认编码。但是,我们可以在程序中给其指定一个规定的字符集进行编码和解码操作。
在byte[] buffer=string.getBytes();中,如果没有给.getBytes();指定字符集,那么在编码过程中,就会按照系统默认的编码格式进行编码。
在输出的过程中。如果没有指定的字符集,程序也会按照运行环境默认的字符集输出。
因此,在java程序的运行过程中,字符的转换过程是:
在java虚拟机(即JVM)对源文件进行编译时,jvm按照系统默认或者按照指定的字符集将源文件解码成JVM能看懂的字符,然后将字符编码成unicode格式存储在内存中。编译后字符 数据会以UNICODE格式存入字节码文件中,生成class文件。
在JVM运行程序时,因为字节码中的字符总是UNICODE格式,所以java读取字节码文件并没有编码转换过程。虚拟机读取文件后,字符数据便以UNICODE格式存储在内存中了。
-------------------------------
在java程序的运行过程中,也就是java程序在内存中执行的过程里。程序内的输入和输出都要考虑字符集的转换问题。
比如:
String string="你静夜思\r\n 李白\r\n 床前明月光,\r\n 疑似地上光;\r\n 举头望明月,\r\n 低头思故乡。\r\n Oh Yh Come On!!!!!";
byte[] buffer=string.getBytes();//该行代码可以将string中的字符串转变成相应字符集中的数字编码,即字节码本程序中系统默认编码为utf-8。
在编译时,string中的所有字符和java源文件一样(其实string字符串包含在java源文件中)在编译时被编码成了unicode格式,编译过程只对java源文件进行操作,不包含目标文件等。
在运行过程中,要将unicode格式的字符串string装到buffer里。此过程需要将unicode格式的string进行编码。如果没有指定编码的格式,比如“.getBytes();”程序就会按照运行
环境默认的编码格式进行编码(我们常用的运行环境一般为eclipse或者操作系统,eclipse的默认编码格式可以自己调整,方法另外查找;中文操作系统默认使用GBK格式),那么在操作系统的控制台上运行时,string就会被编码成GBK格式的字节码存储。但是为了保证不出现乱码问题我们可以对其字符集进行限制(“.getBytes("utf-8");”),这样就会使string按照utf-8格式
进行编码。
-------------------------------
在要将程序中的内容输出到文件里时,比如:
File file=new File("file21.txt");
FileOutputStream fos=new FileOutputStream(file,true);
String string="你静夜思\r\n 李白\r\n 床前明月光,\r\n 疑似地上光;\r\n 举头望明月,\r\n 低头思故乡。\r\n Oh Yh Come On!!!!!";
byte[] buffer=string.getBytes();
/*
for (byte b : buffer)
System.out.println(b);
*/
System.out.println("当前JRE:" + System.getProperty("java.version"));
System.out.println("当前JVM的默认字符集:" + Charset.defaultCharset());
fos.write(buffer);
fos.close();
在此程序中,利用FileOutputStream fos将字符串输出到文件里,如果执行程序之前没有建立file21文件,程序会自动根据buffer=string.getBytes();所指定的字符集建立一个文件。如果在执行程序前已经有目标文件,就会将文件写入到指定文件里,但是要注意字符格式问题,因为字符格式不一致会导致写入的文件乱码。
注:FileOutputStream fos=new FileOutputStream(file,true);当加上true时,会自动在目标文件后添加内容,上述操作才成立。否则就会新建立一个目标文件并且将目标文件的格式个改为和输出的字符串相同的格式。
-----------------------------------
当向程序中输入文件时,例如:
File file=new File("new.txt");
FileInputStream fis=new FileInputStream(file);
byte[] buffer=new byte[(int) file.length()];
fis.read(buffer);
此执行的过程为:
在编译时,JVM虚拟机只会检查和读取java源文件,只要源文件没有错误就可编译通过。而不会对程序需要操作的目标文件执行任何操作。
在执行时,会将fis中的文件读到内存中然后将其读取到java程序里。在读取到程序里的过程中,JVM会将目标文件按照源文件格式进行编码,将编码后的字节码读取到程序中。
在要将其读出时,例如:
//从文件中提取内容
FileInputStream fis=new FileInputStream(file);
buffer=new byte[(int) file.length()];
//读出内容并进行编码,编码的格式是按照源文件的格式进行编码(作用是将将文件内容转换成所有程序都能通用和识别的字节型数组)
fis.read(buffer);
主要关注这部分:
String str=new String(buffer,"gbk");
System.out.println(str);
fis.close();
如果没有给字节码指定字符集,那么就会按照运行环境默认的字符集进行解码 那么如果字符集不一致就会乱码。
java编码原理,java编码和解码问题的更多相关文章
- 编码原理_base64编码原理
1.1 Base64编码原理 1.1.1 概要: Base64是通讯传输中较为常见的编码方式之一. (注意是编码算法,而非加密算法) 参数传输的过程中会经常遇到的一种情况:使用英文不会涉及到乱码, ...
- Mysql编码, Mysql编码流程, Mysql编码顺序, Mysql编码原理, Mysql编码修改依据
编码查看方式以及解释说明: 需要以root用户身份登陆才可以查看数据库编码方式(以root用户身份登陆的命令为:>mysql -u root –p,之后两次输入root用户的密码),查看数据库的 ...
- google protocol buffer——protobuf的编码原理二
这一系列文章主要是对protocol buffer这种编码格式的使用方式.特点.使用技巧进行说明,并在原生protobuf的基础上进行扩展和优化,使得它能更好地为我们服务. 在上一篇文章中,我们主要通 ...
- 字符串编码原理--PHP数组原理与高级应用
基础知识 1.有几种表达方式(查看手册)2.单引号和双引号的区别,双引号解析变量.\n,\t等,八进制与十六进制编码 内部存储方式 c语言中怎么表示字符串,结构体存储了字符指针和长度1.字符串可以用[ ...
- 签名、BOM头、编码、Windows记事本编码、java编码解码的那些事
对于Windows记事本: ANSI :GB2312 java中应使用GBK解码 Unicode :有签名的UTF-16LE java中应使用UTF-16解码 Unicode big endian : ...
- encodeURIComponent编码后java后台的解码 (AJAX中文解决方案)
encodeURIComponent编码后java后台的解码 (AJAX中文解决方案) 同学的毕业设计出现JavaScript用encodeURIComponentt编码后无法再后台解码的问题. 原来 ...
- encodeURIComponent编码后java后台的解码
解决方法一: JavaScript: window.self.location="searchbytext.action?searchtext="+encodeURICompone ...
- java、js的编码、解码
如果在地址栏挂载参数,特别是包含中文,往往要进行编码,取值时再解码,以下是java和js中编码.解码的各自方法. java: @Test public void test3() throws Unsu ...
- Js编码和Java后台解码
1.java.将resultMsg 转为utf-8 (1) resultMsg = URLEncoder.encode(resultMsg, "utf-8"); (2) new S ...
随机推荐
- 巧用location.hash保存页面状态
在我们的项目中,有大量ajax查询表单+结果列表的页面,由于查询结果是ajax返回的,当用户点击列表的某一项进入详情页之后,再点击浏览器回退按钮返回ajax查询页面,这时大家都知道查询页面的表单和结果 ...
- 探索C#之系列目录导航
1. 探索c#之函数创建和闭包 2. 探索c#之尾递归编译器优化 3. 探索c#之不可变数据类型 4. 探索c#之递归APS和CPS 5. 探索c#之一致性Hash详解 6. 探索c#之微型MapRe ...
- JQuery插件定义
一:导言 有些WEB开发者,会引用一个JQuery类库,然后在网页上写一写$("#"),$("."),写了几年就对别人说非常熟悉JQuery.我曾经也是这样的人 ...
- 轻量级表达式树解析框架Faller
有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...
- ABP源码分析二十八:ABP.MemoryDB
这个模块简单,且无实际作用.一般实际项目中都有用数据库做持久化,用了数据库就无法用这个MemoryDB 模块了.原因在于ABP限制了UnitOfWork的类型只能有一个(前文以作介绍),一般用了数据库 ...
- MailKit系列之---查询SearchQuery
对于邮件的唯一Id查询,由于MailKit提供了大量的方法,无法完全讲解完全,所以这里只选择几个来介绍. MailKit通过方法folder.Search来查询邮件的唯一Id,参数是一个SearchQ ...
- CentOS 搭建openVPN
1.安装前准备 # 关闭selinux setenforce 0 sed -i '/^SELINUX=/c\SELINUX=disabled' /etc/selinux/config # 安装open ...
- C++11网络编程
Handy是一个简洁优雅的C++11网络库,适用于linux与Mac平台.十行代码即可完成一个完整的网络服务器. 下面是echo服务器的代码: #include <handy/handy.h&g ...
- 妙用psexec分析关机一直挂起的Windows update 更新
Windows 更新服务对每个IT运维人员来说都不会陌生,而且很多情况下出现的一些不兼容,产品问题通过更新都可很好的解决掉. 小弟近日为一台老爷机服务器安装Windows 产品更新就遇到了意见事情,特 ...
- android使用ImageLoader实现图片缓存(安卓开发必备)
相信大家在学习以及实际开发中基本都会与网络数据打交道,而这其中一个非常影响用户体验的就是图片的缓存了,若是没有弄好图片缓存,用户体验会大大下降,总会出现卡顿情况,而这个问题尤其容易出现在ListVie ...