黑马程序员技术交流社区

标题: 关于转换流默认UTF-8编码格式下读取字符问题 [打印本页]

作者: 菊花爆满山    时间: 2015-9-16 22:03
标题: 关于转换流默认UTF-8编码格式下读取字符问题

  1. import java.io.*;
  2. class EncodeStreamDemo
  3. {
  4.         public static void main(String[] args) throws IOException
  5.         {
  6.                 //writeText();
  7.                 readText();
  8.         }
  9.         public static void readText() throws IOException
  10.         {
  11.                 InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk.txt"),"UTF-8");
  12.                 char [] byt = new char[10];
  13.                 int len = 0;
  14.                 int count = 0;
  15.                 while ((len =isr.read(byt))!=-1)
  16.                 {
  17.                         count++;
  18.                         String s = new String(byt,0,len);
  19.                         System.out.print(s);
  20.                 }
  21.                 System.out.println(count);
  22.                 /*
  23.                 int len = isr.read(byt);
  24.                 String s = new String(byt,0,len);
  25.                 System.out.println(s);
  26.                 isr.close();
  27.                 */
  28.         }
  29.         public static void writeText() throws IOException
  30.         {
  31.                 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");
  32.                 osw.write("你好");
  33.                 osw.close();
  34.         }
  35. }
复制代码

这段代码执行后为什么count的值是2 意思是为什么循环2次

作者: 夸克    时间: 2015-9-16 22:03
本帖最后由 夸克 于 2015-9-17 21:19 编辑

这个问题有意思,以前没想过,占个座等大牛解答~
我说下我自己的理解,抛砖引玉
我实验了下,发现读两次和定义的数组长度,读取的文件有多少字节这些都没有关系。但是竟然跟存的汉字有关
比如存的肯定是“你好”,读两次;现在你去试试存“哈哈”这两个字,只读一次。
跟存储的内容有关,我就想到了UTF-8的特点,UTF-8是变长的,根据左侧位1的个数来决定占用了几个字节(二进制形式下)。就是说,我们认为UTF-8格式下一个汉字占3个字节是不准确的,具体可以去百度下。而且读的过程中好像有半个字的时候会舍弃,挺复杂的,所以我觉得,举个例子可能是读的过程中开始按比如3个字节算一个汉字读,认为读完了。但是还有内容后来又按1个字节读,可以读。

作者: 芝麻糊    时间: 2015-9-16 22:56
两次才把gbk.txt文件读完
作者: Chendamai    时间: 2015-9-17 11:22
byt存满了还没有到流末尾 所以它得再循环一次到了流末尾就等于-1结束了
作者: 生存追求    时间: 2015-9-17 15:59
我自己建了一个gbk.txt文件,写了:
fdsagdshkdkd
fafasnjkjj
afkhakj
faoj
运行结果为:
fdsagdshkdkd
fafasnjkjj
afkhakj
faoj4
没问题的,看看文件名是否一致
作者: 芝麻糊    时间: 2015-9-17 19:07
Chendamai 发表于 2015-9-17 11:22
byt存满了还没有到流末尾 所以它得再循环一次到了流末尾就等于-1结束了

不会吧,txt文件真的是4个字节? 右击属性看看
作者: 15173139267    时间: 2015-9-17 20:42
如图所示,其实就是二次编码问题<乱码>。

作者: 15173139267    时间: 2015-9-17 20:45
朋友,乱码问题。  你在gbk.txt中输入的是中文吧.  <是不是一猜就中>

QQ图片20150917203748.png (180.55 KB, 下载次数: 170)

QQ图片20150917203748.png

作者: 15173139267    时间: 2015-9-17 20:59
15173139267 发表于 2015-9-17 20:42
如图所示,其实就是二次编码问题。

刚刚没有把图传上去,下面那个是我的图。
作者: 15173139267    时间: 2015-9-18 20:18
15173139267 发表于 2015-9-17 20:45
朋友,乱码问题。  你在gbk.txt中输入的是中文吧.

GBK每个汉字两个字节,UTF-8每个汉字三个字节。
作者: 15173139267    时间: 2015-9-18 20:31
15173139267 发表于 2015-9-17 20:45
朋友,乱码问题。  你在gbk.txt中输入的是中文吧.

我发现编码方式越往深处研究。真的就好高深了。 牵扯到二进制、16进制等去了。
作者: 0814java1    时间: 2015-9-18 21:44
生存追求 发表于 2015-9-17 15:59
我自己建了一个gbk.txt文件,写了:
fdsagdshkdkd
fafasnjkjj

GBK可以说是简体中文码表,2个字节表示一个数据
UTF-8是Unicode码表的升级码表,一个汉字需要3个字节来表示,并且他是动态的




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2