黑马程序员技术交流社区
标题:
为什么一个是两个问号??,一个是三个问号???
[打印本页]
作者:
rslheima
时间:
2012-6-26 19:05
标题:
为什么一个是两个问号??,一个是三个问号???
本帖最后由 rslheima 于 2012-6-26 19:13 编辑
为什么同样是用
GBK
编码的“你好”两个字使用不同方法,都用
utf-8
解码,为什么一个是两个问号??,一个是三个问号???
package io.ENCODE;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Encode {
public static void main(String[] args) throws IOException {
System.out.println("使用流操作转换“你好“");
write();
read();
System.out.println("使用编码,解码--”你好“");
encode();
}
//------------------使用gbk编码写入”你好“-------------------------
public static void write() throws IOException{
OutputStreamWriter osw=new OutputStreamWriter(
new FileOutputStream("C:\\Users\\Administrator\\Desktop\\utf.txt"),"gbk");
osw.write("你好");
osw.close();
}
//------------------使用utf-8编码读取“你好”-----------------------
public static void read() throws IOException{
InputStreamReader irs=new InputStreamReader(new FileInputStream("C:\\Users\\Administrator\\Desktop\\utf.txt"),"utf-8");
char [] buf=new char[10];
int ch=0;
ch=irs.read(buf);
System.out.println(new String (buf,0,ch));
}
//-----------------使用字符编码,解码方式,-----------------------
public static void encode() throws UnsupportedEncodingException{
String str="你好";
//-----------------使用gbk编码----------
byte[] b=str.getBytes("gbk");
//System.out.println(Arrays.toString(b));
//----------------使用utf-8解码-----------
String s1=new String(b,"utf-8");
System.out.println(s1);
}
}
复制代码
结果:
使用流操作转换“你好“
??
使用编码,解码--”你好“
???
作者:
陈淑飞
时间:
2012-6-26 19:20
本帖最后由 陈淑飞 于 2012-6-26 19:21 编辑
建议 楼主解决这个问题前,先在百度下 搜下 结果。
出现二个 ?? 问号与 三个??? 问题是为什么,先预猜下,然后带的问题去找答案。这样学习效率会提高很多。
呵呵,不过,也谢谢你提这个问题,让我也学习到了点。从这点来说,你对大家的贡献还是蛮大的。呵呵。
好了 废话说了一堆,说问题吧。
其它打印二个问号与三个问号的区别, 代码上没问题,只能说去找UTF-8与GBK编码有什么区别了。
UTF-8与GBK编码的区别
UTF-8:Unicode Transformation Format-8bit,是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。
GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差。
通过这个,我们可以了解到原来:
UTF-8在给我们中文编码是采用了
三个字节
,而我们自己国家GBK编码对中文编码是采用了
二个字节
。
欧了没?
作者:
张华廷
时间:
2012-6-26 23:50
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class fdsdfs {
public static void main(String[] args) throws IOException {
System.out.println("使用流操作转换“你好“");
write();
read();
System.out.println("使用编码,解码--”你好“");
encode();
}
//------------------使用gbk编码写入”你好“-------------------------
public static void write() throws IOException{
OutputStreamWriter osw=new OutputStreamWriter(
new FileOutputStream("C:\\Users\\Administrator\\Desktop\\utf.txt"),"gbk");
osw.write("你好");
osw.close();
}
//------------------使用utf-8编码读取“你好”-----------------------
public static void read() throws IOException{
InputStreamReader irs=new InputStreamReader(new FileInputStream("C:\\Users\\Administrator\\Desktop\\utf.txt"),"gbk");//
把utf-8改为gbk就可以了
char [] buf=new char[10];
int ch=0;
ch=irs.read(buf);
System.out.println(new String (buf,0,ch));
}
//-----------------使用字符编码,解码方式,-----------------------
public static void encode() throws UnsupportedEncodingException{
String str="你好";
//-----------------使用gbk编码----------
byte[] b=str.getBytes("gbk");
//System.out.println(Arrays.toString(b));
//----------------使用utf-8解码-----------
String s1=new String(b,"gbk");//
把utf-8改为gbk就可以了
System.out.println(s1);
}
}
结果:使用流操作转换“你好“
你好
使用编码,解码--”你好“
你好
作者:
周朋飞
时间:
2012-6-27 00:16
第一个问题:为什么是两个?号,你存的时候按gbk去存,那么你存的文件大小是4个字节,gbk当中两个字节表示一个汉字,假如存到硬盘的数据时 -12 -23 -34-56 ,那么前两个表示你 后两个表示好字,然而你读的时候你指定用utf-8去读取,utf-8是按三个字节来读的,那么就会取出 -12 -23 -34去utf-8表上查一查没有这个汉字 就给你返回一个?号,那么最后一个字节肯定也是找不到啊 就去未知字符去找 所以也是一个?号
第二个问题有点难度,需要查看dataInputStream下面有个utf-8修改表,我们可以通过一些方法获得你好这两个字的二进制数字,得出的结果是
11000100
11100011
10111010
11000011
当你用utf去解码的时候,因为第一个是110开头,按两个字节去读,但是第二个字节不是10 所以 第一个字节出现一个问号,然后接着读 第二个字节1110应该按三个字节去读
但是四个字节是110开头不是10开头所以又出现第二个问号,那最后一个就是一个问号了 希望能帮到你
作者:
周朋飞
时间:
2012-6-27 00:31
补充一点:第一个出现两个??的原因就是我上面说的 为什么呢 我给你加一段代码 你就知道了 在你read方法里加上System.out.println(a+"");然后你取的时候new String (buf,0,ch)) 这个ch的值是2 所以呢 就是按三个字节来处理的 最后一个字节 作为一个问号
作者:
王涛
时间:
2012-6-27 00:54
第一个问题:
使用流操作转换“你好“
??
因为你是用的使用gbk编码写入”你好“,在他的编码表中,每个中字占2个字节。
“你好”占了4个字节
然后你使用UTF-8读取“你好”,在他的编码表中,每个中字占3个字节。
当她读的时候,先拿了3个字节去查编码表,没有,就返回一个未知字符?
剩下1个,她又去查编码表,还没有,又返回一个未知字符?
第二个问题:
使用编码,解码--”你好“
???
用的GBK编码,还是4个字节
主要是UTF-8解码
因为UTF-8并不是每个字都是3个字节的,而是根据二进制位的开头来确定是占1个字节,还是2字节,或者是3个
然后她根据那4个字节的二进制位,得到有一个占2个字节,有两个占1个字节相似的未知字符,然后输出了他们,也就是???,就想楼上说的
你可以看下基础视频中的21天,06和07,一个是讲转换,一个讲编码的
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2