
这是Unicode编码,你只要把它按下面方法打印即可:
String s="\u8c01\u80fd\u591f\u7ed9\u6211\u98ce\u9669\u6295\u8d44\u54e6!\u6211\u60f3\u501f\u5341\u4e07\u529e\u4e00\u4e2a\u517b\u6b96\u5382\u3002\u6211\u53ef\u662f\u6709\u5bb6\u5ead\u62c5\u4fdd\u7684\u54e6!#\u4e0a\u7f51\u7231\u901b\u4ec0\u4e48#";
Systemoutprintln(s);
打印出:
谁能够给我风险投资哦!我想借十万办一个养殖厂。我可是有家庭担保的哦!#上网爱逛什么#
可以通过以下方法来进行编码格式判断,输入一个字符串,之后返回字符串编码类型。
public static String getEncoding(String str) {
String encode = "GB2312";
try {
if (strequals(new String(strgetBytes(encode), encode))) { //判断是不是GB2312
String s = encode;
return s; //是的话,返回“GB2312“,以下代码同理
}
} catch (Exception exception) {
}
encode = "ISO-8859-1";
try {
if (strequals(new String(strgetBytes(encode), encode))) { //判断是不是ISO-8859-1
String s1 = encode;
return s1;
}
} catch (Exception exception1) {
}
encode = "UTF-8";
try {
if (strequals(new String(strgetBytes(encode), encode))) { //判断是不是UTF-8
String s2 = encode;
return s2;
}
} catch (Exception exception2) {
}
encode = "GBK";
try {
if (strequals(new String(strgetBytes(encode), encode))) { //判断是不是GBK
String s3 = encode;
return s3;
}
} catch (Exception exception3) {
}
return ""; //如果都不是,说明输入的内容不属于常见的编码格式。
}
byte[] b=stringgetBytes("GB2312");//使用GB2312编码方式对字符串string进行编码
//这时要想将字节数组b的内容正确解码只能使用GB2312的编码方式进行解码,即
String str=new String(b,"GB2312");//这里若使用UTF-8编码方式来进行解码就会乱码
//将eclipse默认的编码方式改为UTF-8,只是用该编码方式对java源文件进行编码保存
//这个对new String(stringgetBytes("GB2312"),"UTF-8")没啥影响的
//因为从java源文件获取字符串string时,已经通过UTF-8编码方式进行解码了
//而stringgetBytes("GB2312")是使用指定的编码方式对字符串string进行从新编码
//这两者之间没啥关系的
public class Demo
{
public static void main(String[] args)
{
String str="例子";
//数组bm保存的就是"例子"的Unicode代码点(10进制)
int[] bm=new int[strlength()];
for(int i=0;i<strlength();i++)
{
bm[i]=strcodePointAt(i);
Systemoutprint(""+bm[i]+" ");
}
}
}
public
byte[]
getBytes(String
charsetName)
使用指定的字符集将此String编码为byte序列,结果存在一个byte数组中
public
String(byte[]
bytes,
String
charsetName)
通过使用指定的
charset
解码指定的
byte
数组,构造一个新的
String。
在网络传输中,信息都是以字节序列的方式传输的。所以,发送方的String要按照某种编码方式(如UTF-8,GBK)编码为字节序列,在网络中传输后,接收方取得这个字节序列,按照相同的编码方式将字节序列解码为String。
请看下面的代码片段:
String
name
=
"张三";
byte[]
b1
=
namegetBytes("UTF-8");
String
name1
=
new
String(b1,
"UTF-8");
//编码解码相同,正常显示
Systemoutprintln(name1);
String
name2
=
new
String(b1,
"GBK");
//编码解码不同,乱码
Systemoutprintln(name2);
byte[]
b2
=
namegetBytes("GBK");
String
name3
=
new
String(b2,
"GBK");
//编码解码相同,正常显示
Systemoutprintln(name3);
String
name4
=
new
String(b2,
"UTF-8");
//编码解码不同,乱码
Systemoutprintln(name4);
至于你的那个情况,要先用gbk编码,然后再用utf-8解码才能获得正常的字符串,我估计是因为
1传输过来的字节码是用utf-8编码的,假设字节码为b。
2你获得的那个字符串,假设为s,是用gbk对b进行解码获得的字符串,所以是乱码。
3你使用gbk对s进行编码,用gbk解码之后再编码,于是获得了原来的b。
4你使用utf-8解码,所以获得了正常的字符串。
简单的说:
b
->
(gbk解码)
->
乱码
->
[此处开始是你做的](gbk编码)
->
b
->
(utf-8解码)
->
正常字符串
研究完编码收获会不小的,对以后理解Java的输入输出(尤其是网络通信和文件读写)都很有帮助。
问题一:在java中读取文件时应该采用什么编码?
Java读取文件的方式总体可以分为两类:按字节读取和按字符读取。按字节读取就是采用InputStreamread()方法来读取字节,然后保存到一个byte[]数组中,最后经常用new String(byte[]);把字节数组转换成String。在最后一步隐藏了一个编码的细节,new String(byte[]);会使用 *** 作系统默认的字符集来解码字节数组,中文 *** 作系统就是GBK。而我们从输入流里读取的字节很可能就不是GBK编码的,因为从输入流里读取的字节编码取决于被读取的文件自身的编码。举个例子:我们在D:盘新建一个名为demotxt的文件,写入”我们。”,并保存。此时demotxt编码是ANSI,中文 *** 作系统下就是GBK。此时我们用输入字节流读取该文件所得到的字节就是使用GBK方式编码的字节。那么我们最终new String(byte[]);时采用平台默认的GBK来编码成String也是没有问题的(字节编码和默认解码一致)。试想一下,如果在保存demotxt文件时,我们选择UTF-8编码,那么该文件的编码就不在是ANSI了,而变成了UTF-8。仍然采用输入字节流来读取,那么此时读取的字节和上一次就不一样了,这次的字节是UTF-8编码的字节。两次的字节显然不一样,一个很明显的区别就是:GBK每个汉字两个字节,而UTF-8每个汉字三个字节。如何我们最后还使用new String(byte[]);来构造String对象,则会出现乱码,原因很简单,因为构造时采用的默认解码GBK,而我们的字节是UTF-8字节。正确的办法就是使用new String(byte[],”UTF-8”);来构造String对象。此时我们的字节编码和构造使用的解码是一致的,不会出现乱码问题了。
说完字节输入流,再来说说字节输出流。
我们知道如果采用字节输出流把字节输出到某个文件,我们是无法指定生成文件的编码的(假设文件以前不存在),那么生成的文件是什么编码的呢?经过测试发现,其实这取决于写入的字节编码格式。比如以下代码:
OutputStream out = new FileOutputStream("d:\\demotxt");
outwrite("我们"getBytes());
getBytes()会采用 *** 作系统默认的字符集来编码字节,这里就是GBK,所以我们写入demotxt文件的是GBK编码的字节。那么这个文件的编码就是GBK。如果稍微修改一下程序:outwrite("我们"getBytes(“UTF-8”));此时我们写入的字节就是UTF-8的,那么demotxt文件编码就是UTF-8。这里还有一点,如果把”我们”换成123或abc之类的ascii码字符,那么无论是采用getBytes()或者getBytes(“UTF-8”)那么生成的文件都将是GBK编码的。
这里可以总结一下,InputStream中的字节编码取决文件本身的编码,而OutputStream生成文件的编码取决于字节的编码。
下面说说采用字符输入流来读取文件。
首先,我们需要理解一下字符流。其实字符流可以看做是一种包装流,它的底层还是采用字节流来读取字节,然后它使用指定的编码方式将读取字节解码为字符。说起字符流,不得不提的就是InputStreamReader。以下是java api对它的说明: InputStreamReader是字节流通向字符流的桥梁:它使用指定的charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,否则可能接受平台默认的字符集。说到这里其实很明白了,InputStreamReader在底层还是采用字节流来读取字节,读取字节后它需要一个编码格式来解码读取的字节,如果我们在构造InputStreamReader没有传入编码方式,那么会采用 *** 作系统默认的GBK来解码读取的字节。还用上面demotxt的例子,假设demotxt编码方式为GBK,我们使用如下代码来读取文件:
InputStreamReader in = new InputStreamReader(new FileInputStream(“demotxt”));
那么我们读取不会产生乱码,因为文件采用GBK编码,所以读出的字节也是GBK编码的,而InputStreamReader默认采用解码也是GBK。如果把demotxt编码方式换成UTF-8,那么我们采用这种方式读取就会产生乱码。这是因为字节编码(UTF-8)和我们的解码编码(GBK)造成的。解决办法如下:
InputStreamReader in = new InputStreamReader(new FileInputStream(“demotxt”),”UTF-8”);
给InputStreamReader指定解码编码,这样二者统一就不会出现乱码了。
下面说说字符输出流。
字符输出流的原理和字符输入流的原理一样,也可以看做是包装流,其底层还是采用字节输出流来写文件。只是字符输出流根据指定的编码将字符转换为字节的。字符输出流的主要类是:OutputStreamWriter。Java api解释如下:OutputStreamWriter 是字符流通向字节流的桥梁:使用指定的 charset 将要向其写入的字符编码为字节。它使用的字符集可以由名称指定或显式给定,否则可能接受平台默认的字符集。说的很明白了,它需要一个编码将写入的字符转换为字节,如果没有指定则采用GBK编码,那么输出的字节都将是GBK编码,生成的文件也是GBK编码的。如果采用以下方式构造OutputStreamWriter:
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(“ddtxt”),”UTF-8”);
那么写入的字符将被编码为UTF-8的字节,生成的文件也将是UTF-8格式的。
问题二: 既然读文件要使用和文件编码一致的编码,那么javac编译文件也需要读取文件,它使用什么编码呢?
这个问题从来就没想过,也从没当做是什么问题。正是因为问题一而引发的思考,其实这里还是有东西可以挖掘的。下面分三种情况来探讨,这三种情况也是我们常用的编译java源文件的方法。
1javac在控制台编译java类文件。
通常我们手动建立一个java文件Demojava,并保存。此时Demojava文件的编码为ANSI,中文 *** 作系统下就是GBK然后使用javac命令来编译该源文件。”javac Demojava”。Javac也需要读取java文件,那么javac是使用什么编码来解码我们读取的字节呢?其实javac采用了 *** 作系统默认的GBK编码解码我们读取的字节,这个编码正好也是Demojava文件的编码,二者一致,所以不会出现乱码情况。让我们来做点手脚,在保存Demojava文件时,我们选择UTF-8保存。此时Demojava文件编码就是UTF-8了。我们再使用”javac Demojava”来编译,如果Demojava里含有中文字符,此时控制台会出现警告信息,也出现了乱码。究其原因,就是因为javac采用了GBK编码解码我们读取的字节。因为我们的字节是UTF-8编码的,所以会出现乱码。如果不信的话你可以自己试试。那么解决办法呢?解决办法就是使用javac的encoding参数来制定我们的解码编码。如下:javac -encoding UTF-8 Demojava。这里我们指定了使用UTF-8来解码读取的字节,由于这个编码和Demojava文件编码一致,所以不会出现乱码情况了。
2Eclipse中编译java文件。
我习惯把Eclipse的编码设置成UTF-8。那么每个项目中的java源文件的编码就是UTF-8。这样编译也从没有问题,也没有出现过乱码。正是因为这样才掩盖了使用javac可能出现的乱码。那么Eclipse是如何正确编译文件编码为UTF-8的java源文件的呢?唯一的解释就是Eclipse自动识别了我们java源文件的文件编码,然后采取了正确的encoding参数来编译我们的java源文件。功劳都归功于IDE的强大了。
3使用Ant来编译java文件。
Ant也是我常用的编译java文件的工具。首先,必须知道Ant在后台其实也是采用javac来编译java源文件的,那么可想而知,1会出现的问题在Ant中也会存在。如果我们使用Ant来编译UTF-8编码的java源文件,并且不指定如何编码,那么也会出现乱码的情况。所以Ant的编译命令<javac>有一个属性” encoding”允许我们指定编码,如果我们要编译源文件编码为UTF-8的java文件,那么我们的命令应该如下:
<javac destdir="${classes}" target="14" source="14" deprecation="off" debug="on" debuglevel="lines,vars,source" optimize="off" encoding="UTF-8">
指定了编码也就相当于”javac –encoding”了,所以不会出现乱码了。
问题三:tomcat中编译jsp的情况。
这个话题也是由问题二引出的。既然javac编译java源文件需要采用正确的编码,那么tomcat编译jsp时也要读取文件,此时tomcat采用什么编码来读取文件?会出现乱码情况吗?下面我们来分析。
我们通常会在jsp开头写上如下代码:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
我常常不写pageEncoding这个属于,也不明白它的作用,但是不写也没出现过乱码情况。其实这个属性就是告诉tomcat采用什么编码来读取jsp文件的。它应该和jsp文件本身的编码一致。比如我们新建个jsp文件,设置文件编码为GBK,那么此时我们的pageEncoding应该设置为GBK,这样我们写入文件的字符就是GBK编码的,tomcat读取文件时采用也是GBK编码,所以能保证正确的解码读取的字节。不会出现乱码。如果把pageEncoding设置为UTF-8,那么读取jsp文件过程中转码就出现了乱码。上面说我常常不写pageEncoding这个属性,但是也没出现过乱码,这是怎么回事呢?那是因为如果没有pageEncoding属性,tomcat会采用contentType中charset编码来读取jsp文件,我的jsp文件编码通常设置为UTF-8,contentType的charset也设置为UTF-8,这样tomcat使用UTF-8编码来解码读取的jsp文件,二者编码一致也不会出现乱码。这只是contentType中charset的一个作用,它还有两个作用,后面再说。可能有人会问:如果我既不设置pageEncoding属性,也不设置contentType的charset属性,那么tomcat会采取什么编码来解码读取的jsp文件呢?答案是iso-8859-1,这是tomcat读取文件采用的默认编码,如果用这种编码来读取文件显然会出现乱码。
问题四:输出。
问题二和问题三分析的过程其实就是从源文件àclass文件过程中的转码情况。最终的class文件都是以unicode编码的,我们前面所做的工作就是把各种不同的编码转换为unicode编码,比如从GBK转换为unicode,从UTF-8转换为unicode。因为只有采用正确的编码来转码才能保证不出现乱码。Jvm在运行时其内部都是采用unicode编码的,其实在输出时,又会做一次编码的转换。让我们分两种情况来讨论。
1java中采用Sysoutoutprintln输出。
比如:Sysoutoutprintln(“我们”)。经过正确的解码后”我们”是unicode保存在内存中的,但是在向标准输出(控制台)输出时,jvm又做了一次转码,它会采用 *** 作系统默认编码(中文 *** 作系统是GBK),将内存中的unicode编码转换为GBK编码,然后输出到控制台。因为我们 *** 作系统是中文系统,所以往终端显示设备上打印字符时使用的也是GBK编码。因为终端的编码无法手动改变,所以这个过程对我们来说是透明的,只要编译时能正确转码,最终的输出都将是正确的,不会出现乱码。在Eclipse中可以设置控制台的字符编码,具体位置在Run Configuration对话框的Common标签里,我们可以试着设置为UTF-8,此时的输出就是乱码了。因为输出时是采用GBK编码的,而显示却是使用UTF-8,编码不同,所以出现乱码。
2jsp中使用outprintln()输出到客户端浏览器。
Jsp编译成class后,如果输出到客户端,也有个转码的过程。Java会采用 *** 作系统默认的编码来转码,那么tomcat采用什么编码来转码呢?其实tomcat是根据<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>中contentType的charset参数来转码的,contentType用来设置tomcat往浏览器发送HTML内容所使用的编码。Tomcat根据这个编码来转码内存中的unicode。经过转码后tomcat输出到客户端的字符编码就是utf-8了。那么浏览器怎么知道采取什么编码格式来显示接收到的内容呢?这就是contentType的charset属性的第三个作用了:这个编码会在>
以上就是关于java中这种编码方式是什么全部的内容,包括:java中这种编码方式是什么、java 中如何查看字符串的编码类型、请问java如何改变字符串的编码方式等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)