经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
6.4(java学习笔记)转换流
来源:cnblogs  作者:gcmh  时间:2018/11/2 9:19:52  对本文有异议

一、乱码问题

 

我们来看下列例子:  

  1. public class ConStream {
  2. //当前平台默认采用GBK
  3. public static void main(String[] args){
  4. String str = "依风";
  5. byte[] by = new byte[48];
  6. byte[] bz = new byte[48];
  7. try {
  8. by = str.getBytes("UTF-8");//设置编码方式为utf-8,即将依风以utf-8的个数转换为byte
  9. bz = str.getBytes("GBK");
  10. } catch (UnsupportedEncodingException e) {
  11. // TODO Auto-generated catch block
  12. e.printStackTrace();
  13. }
  14. System.out.println(new String(by));//解码,默认采用平台默认格式,此处为GBK,与编码格式不同会产生乱码
  15. System.out.println(new String(bz,0,3));//编码与解码采用格式相同,但解码的字节缺少,会出现乱码
  16. System.out.println(new String(bz));//编码解码格式相同,且字符为缺少,解码正常不会出现乱码
  17. }
  18. }
  1. 运行结果:
    渚濋
  2. ?
  3. 依风

 

eclipse采用的编码格式,在菜单栏点击Windows-->Preferences-->General-->Workspace 查看默认编码方式

 

可以看到上面出现乱码的主要原因有两个:

1.编码和解码格式不统一。

2.字节丢失。

 

而转换流主要就是解决第一个问题的,它可以在读取和写入时指定编码格式,这样统一后就可以避免乱码问题。

 

二、 InputStreamReader & OutputStreamWtriter

    InputStreamReader是从字节流到字符流的桥梁:它读取字节并使用指定的字符集(UTF-8、GBK等)将它们解码成字符。

    OutputStreamWriter是从字符流到字节流的桥梁:写入其中的字符使用指定的字符集(UTF-8、GBK等)编码为字节。

 

三、构造方法

  OutputStreamWriter(OutputStream out, String charsetName)

  InputStreamReader(InputStream in, String charsetName)

  初始化传递进去的是输入输出流对象,charseName是指定的编码格式。

  剩下的操作方法与输入输出流类似。

 

四、例子

  

  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.io.InputStreamReader;
  10. import java.io.OutputStream;
  11. import java.io.OutputStreamWriter;
  12. public class ConStream {
  13. public static void main(String[] args){
  14. // File f = new File("F:\\依风\\Desktop\\UTF-8.txt");
  15. File f = new File("F:\\依风\\Desktop\\test.txt");
  16. String write = "依风\n依风\n依风";
  17. String read;
  18. try {
  19. char []c = new char[1024];
  20. //字节输入输出流-->转换流-->字符缓冲流
  21. //以一种编码格式写入
  22. OutputStream w = new FileOutputStream(f);
  23. OutputStreamWriter ow = new OutputStreamWriter(w,"GBK");//将字符转换为GBK格式的字节码并写入
  24. BufferedWriter buffW = new BufferedWriter(ow);
  25. buffW.write(write);
  26. buffW.flush();
  27. buffW.close();
  28. w.close();
  29. //将写入的数据
  30. InputStream r = new FileInputStream(f);//字节流
  31. InputStreamReader ir = new InputStreamReader(r,"UTF-8");//将读入GBK格式的字节码,并用UTF-8格式转换为字符
  32. BufferedReader buffR = new BufferedReader(ir);//字符缓冲流
  33. while(null != (read = buffR.readLine())){
  34. System.out.println(read);
  35. }
  36. buffR.close();
  37. r.close();
  38. } catch (FileNotFoundException e) {
  39. // TODO Auto-generated catch block
  40. e.printStackTrace();
  41. } catch (IOException e) {
  42. // TODO Auto-generated catch block
  43. e.printStackTrace();
  44. }
  45. }
  46. }
  1. 运行结果:
  2. ????
  3. ????
  4. ????

先将字符串以GBK方式编码成字节,然后将GBK格式的字节写入文件。

然后将GBK格式的字节以UTF-8格式解码成字符。

上列代码运行后显示的是乱码,因为写入和读取采用的编码方式不一样。

看个图更好理解:

 

 可见转换流主要就两个功能:

1、字节流与字符流字节转换的桥梁

2、指定字节转换为字符的编码方式

 

如果把上述代码中的读、写编码格式一致,则不会出现乱码。反之则会出现乱码。

 

还要一点需要注意:

文件打开时采取的解码方式与程序写入时的编码方式无关。

举个例子,假如我是将字符串转换为GBK格式的字节,然后将GBK格式的字节写入记事本(*.txt)。

我们打开记事本时记事本首先要解码(将二进制的字节转换为字符),但此时采用的解码规则不一定是GBK。

可能是GBK,也可能是UTF-8。记事本采取的解码规则是记事本本身绝对的,记事本会根据本身存储的字节信息进行判断,

然后选取对应的编码,这个判断大多数情况下时准确的但也有例外。

 

例如在记事本中写入“连通”,然后另存为指定下编码规则为ANSI,即在windows平台是采用下GBK编码规则。

然后再次打开记事本会发现显示的是乱码。因为“连通”的GBK格式编码和UTF-8格式的编码“类型”,所以记事本会用UTF-8的方式进行解码。

采用GBK编码方式的字节码用UTF-8编码方式解码就会出现乱码问题。

 

输入连通

另存为,修改编码规则为ANSI(GBK)

 

保存退出,然后再次打开该文本。

我们再次点击另存为:

编码中显示的UTF-8就代表记事本当前的编码规则。

也就是说我们输入“连通”然后用GBK格式保存,记事本自己判断这个编码是UTF-8,然后采用UTF-8方式解码,然后我们看到的就是乱码。

当然这只是个例,换一些别的字符采用上述操作不会出现乱码。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号