今天,一位同事遇到一个编码问题,如下
运行环境:Centos 6.* 【LANG zh_CN.GB18030】
编程语言:java
需求描述:从GBK编码的db2数据库中读取数据,并通过java语言生成一个UTF-8格式的XML文件,然后再通过java进行zip压缩;
问题描述:生成的XML文件部分中文尾部乱码;
其实,我对java不熟,所以也到网上找各种资料,寻求的问题是【java GBK转UTF8】:
有这样的一篇回答我觉得讲的蛮清晰的:
作者:温悦
链接:https://www.zhihu.com/question/20361462/answer/14899233
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【内容如下】
好吧,看来问的人和回答的人都不一定清楚什么是“编码和编码格式”,以及如何理解“java中字符串的编码”;
首先明确几点:unicode是一种“编码”,所谓编码就是一个编号(数字)到字符的一种映射关系,就仅仅是一种一对一的映射而已,可以理解成一个很大的对应表格GBK、UTF-8是一种“编码格式”,是用来序列化或存储1中提到的那个“编号(数字)”的一种“格式”;
GBK和UTF-8都是用来序列化或存储unicode编码的数据的,但是分别是2种不同的格式; 他们俩除了格式不一样之外,他们所关心的unicode编码范围也不一样,utf-8考虑了很多种不同国家的字符,涵盖整个unicode码表,所以其存储一个字符的编码的时候,使用的字节长度也从1字节到4字节不等;而GBK只考虑中文——在unicode中的一小部分——的字符,的编码,所以它算好了只要2个字节就能涵盖到绝大多数常用中文(2个字节能表示6w多种字符),所以它存储一个字符的时候,所用的字节长度是固定的;
上述2个概念不懂的请马上google,下面不再赘述;我下面说说这个问题本身...的问题在哪里首先java的string使用的编码是unicode,但是,当string存在于内存中时(也就是当程序运行时、你在代码中用string类型的引用对它进行操作时、也就是string没有被存在文件中且也没有在网络中传输(序列化)时),是“只有编码而没有编码格式的”,所以java程序中的任何String对象,说它是gbk还是utf-8都是错的,gbk和utf-8是编码格式而不是编码,String在内存中不需要“编码格式”(记住编码格式是在存文件或序列化的时候使用的), 它只是一个unicode的字符串而已所以java里面String是不带编码格式的,而String.toByteArray(charsetName)得到的byteArray是带编码格式的,格式就是你传入的'charsetName',我们不妨把toByteArray的这个过程叫做“编码”;另外,new String(byte[], charsetName)是把一个byte数组(带编码格式)以charsetName指定的编码格式翻译为一个不带编码格式的String对象,我们不妨把这个过程叫“解码”;
最后,总结了两种方法:
【方法1:生成UTF-8文件】
import java.nio.charset.Charset;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
public class HelloWorld {
public static void main(String[] args) {
System.out.println(Charset.defaultCharset());
try {
String nbuf = "你好"; //这是个unicode
System.out.println(nbuf); //输出你好
FileOutputStream out = new FileOutputStream("1.txt", false);
byte[] b = nbuf.getBytes("UTF-8"); //unicode->utf-8
for (byte temp:b) {
out.write(temp);
}
out.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
【方法2:生成UTF-8文件】
import java.nio.charset.Charset;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
public class HelloWorld {
public static void main(String[] args) {
System.out.println(Charset.defaultCharset());
try {
String nbuf = "你好"; //这是个unicode
System.out.println(nbuf); //输出你好
FileOutputStream out = new FileOutputStream("1.txt", false);
OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8");
osw.write(nbuf);
osw.flush();
osw.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
当然,UTF-8转GBK也是类似的;
网友评论