java里关于String的编码与解码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java里关于String的编码与解码相关的知识,希望对你有一定的参考价值。

String的getBytes(charset)方法是解码还是编码啊?

我在网上获取了一串包含中文的字符串直接在eclipse上打印是乱码,经过转换
byte[] b2=s.getBytes("gbk");
String ss=new String(b2,"utf-8");
然后再打印就没问题了。
api上说getBytes的工作是解码,那样的话String ss=new String(b2,"utf-8");就是重新编码了?
utf-8中不是不包含中文吗?!那怎么打印出的中文啊?

从语言编码的角度,getBytes(charset)不是解码、也不是编码,是转换。API 说的是针对数据的角度。把一个整体的String分解成byte[]了。

byte[] b2=s.getBytes("gbk");
String ss=new String(b2,"utf-8");

从GBK转换成UTF-8。

UTF8包含更多的文字量。
参考技术A byte[] b2=s.getBytes("gbk"); 表示按照gbk进行解码。

String ss=new String(b2,"utf-8");表示按照utf-8重新编码
参考技术B utf-8是包含中文的,utf-8包含所有的字符 参考技术C 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 = name.getBytes("UTF-8");
String name1 = new String(b1, "UTF-8"); //编码解码相同,正常显示
System.out.println(name1);
String name2 = new String(b1, "GBK"); //编码解码不同,乱码
System.out.println(name2);

byte[] b2 = name.getBytes("GBK");
String name3 = new String(b2, "GBK"); //编码解码相同,正常显示
System.out.println(name3);
String name4 = new String(b2, "UTF-8"); //编码解码不同,乱码
System.out.println(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如何进行Base64的编码(Encode)与解码(Decode)?

关于base64编码Encode和Decode解码的几种方式
Base64是一种能将任意Binary资料用64种字元组合成字串的方法,而这个Binary资料和字串资料彼此之间是可以互相转换的,十分方便。在实际应用上,Base64除了能将Binary资料可视化之外,也常用来表示字串加密过后的内容。如果要使用Java 程式语言来实现Base64的编码与解码功能,可以参考本篇文章的作法。

早期作法
早期在Java上做Base64的编码与解码,会使用到JDK里sun.misc套件下的BASE64Encoder和BASE64Decoder这两个类别,用法如下:

final BASE64Encoder encoder = new BASE64Encoder();
final BASE64Decoder decoder = new BASE64Decoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encode(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decodeBuffer(encodedText), "UTF-8"));

final BASE64Encoder encoder = new BASE64Encoder();
final BASE64Decoder decoder = new BASE64Decoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encode(textByte);
System.out.println(encodedText);

//解码
System.out.println(new String(decoder.decodeBuffer(encodedText), "UTF-8"));

从以上程式可以发现,在Java中用Base64一点都不难,不用几行程式码就解决了!只是这个sun.misc套件所提供的Base64功能,编码和解码的效率并不太好,而且在以后的Java版本可能就不被支援了,完全不建议使用。

Apache Commons Codec作法
Apache Commons Codec有提供Base64的编码与解码功能,会使用到org.apache.commons.codec.binary套件下的Base64类别,用法如下:

final Base64 base64 = new Base64();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = base64.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(base64.decode(encodedText), "UTF-8"));

final Base64 base64 = new Base64();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = base64.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(base64.decode(encodedText), "UTF-8"));

以上的程式码看起来又比早期用sun.misc套件还要更精简,效能实际执行起来也快了不少。缺点是需要引用Apache Commons Codec,很麻烦。

Java 8之后的作法
Java 8的java.util套件中,新增了Base64的类别,可以用来处理Base64的编码与解码,用法如下:

final Base64.Decoder decoder = Base64.getDecoder();
final Base64.Encoder encoder = Base64.getEncoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decode(encodedText), "UTF-8"));

final Base64.Decoder decoder = Base64.getDecoder();
final Base64.Encoder encoder = Base64.getEncoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decode(encodedText), "UTF-8"));

与sun.misc套件和Apache Commons Codec所提供的Base64编解码器来比较的话,Java 8提供的Base64拥有更好的效能。实际测试编码与解码速度的话,Java 8提供的Base64,要比sun.misc套件提供的还要快至少11倍,比Apache Commons Codec提供的还要快至少3倍。因此在Java上若要使用Base64,这个Java 8底下的java .util套件所提供的Base64类别绝对是首选!

以上是关于java里关于String的编码与解码的主要内容,如果未能解决你的问题,请参考以下文章

关于乱码

关于前台js编码后台java解码

关于PHP二进制安全的解释

Python8_关于编码解码和utf-8

数据的编码和解码--java例子

请问一个关于URL中汉字编码解码的问题