问题:

使用字节流读取文本文件时,会将一个汉字劈成两半,一次只能读一半出来,产生了乱码,无法使用。就算是一次读取2个字节出来,也依然不能解决问题。

如何解决乱码问题,读出完整的汉字和中英文混杂的整篇文章呢?


  1.    char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中当然可以存储汉字啦。所有字符均以2个字节存储。
  2. 这个方法使用一个byte的数组作为一个缓冲区,每次从数据源中读取和缓冲区大小(二进制位)相同的数据并将其存在缓冲区中。当然byte数组中存放的仍然是0-255的整数,将二进制转换为十进制这个过程仍然是read方法实现的。
  3. 当然byte数组中存放的仍然是0-255的整数,将二进制转换为十进制这个过程仍然是read方法实现的。
  4. 需要注意的是,虽然我们可以指定缓冲区的大小,但是read方法在读取数据的时候仍然是按照字节来读取的。在utf-8等变长编码中,一个复杂字符(比如汉字)所占字节往往大于1,并且长度往往是不固定的。(参照UTF-8编码规则)按照字节读取数据会将字符割裂,这就导致我们在使用read(byte[] b)方法读取文件时,虽然指定了缓冲区的大小,但是仍然会出现乱码。

       解决办法 :先读一个字节出来,判断是否是双字节字符(如汉字)的一半,如果是,就再读一个字节进来。然后,将两次读取的内容组装在一起,就是一个完整的汉字了。就算是有多字节的,未来也是可以照此思路解决的。


关键代码 如下:


    

byte [] bytes1=new byte[1]; //创建英文数组,准备接收字符串,存放1个字节
                byte [] bytes2=new byte[2]; //处理中文,准备接收字符串,存放2个字节(双字节) 



                if (fis.available()!=-1){ //如果多次读取,要用while,此处从简 


                    int size=0; 

                    int j= 0; //第几次读取 


                    while ((size = fis.read(bytes1))!=-1){ 

                        j++; //读取次数 

                        sBytes = new String(bytes1);     

                        //如果读取到的bytes[0]<0,说明是中文的半个字符,则再读取一个字节进来 

                        if (bytes1[0]<0){ 

                            bytes2[0]=bytes1[0]; 

                            fis.read(bytes1); 

                            bytes2[1]= bytes1[0]; 

                            sBytes = new String(bytes2);//重新组装                                 

                        } 

                        sAll=sAll + sBytes;    // sAll:文件的总内容 

                        System.out.println("第"+j+ "次,内容sBytes:"+ sBytes+ "\t"+ "size:" 

                                        + size+ "\t"+ bytes1[0]);  // (char)bytes[0] 

                    }