黑马程序员技术交流社区

标题: 关于字符流复制unicode编码的文本文件的问题 [打印本页]

作者: 袁冬梅    时间: 2012-3-21 03:50
标题: 关于字符流复制unicode编码的文本文件的问题
本帖最后由 袁冬梅 于 2012-3-21 04:04 编辑

做题的时候遇到字符流和字节流处理复制文本文件的一点小问题有点迷糊,请大家帮帮忙!
之前做基础测试的时候,有一题要我们写一个最快的复制文件的程序。于是我去查了一下,发现复制文件的处理方法可以通过字节流和字符流两种方式来处理。一般来说,二进制文件比如:音频之类的只能通过字节流来处理,文本文件[本质上也可以说是二进制文件]可以通过字符流和字节流两种方式来处理。但是在查资料的时候,看到有人说文本文件最好用字符流来处理,因为字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。就是说,字节流处理Unicode编码的文件时有可能出现乱码。
然后我为了看看效果,就自己看着API编了一个小程序。实验用的文本文件里面的内容是unicode编码才能保存下来的字符。然后我分别用字节流方式和字符流方式来复制这个文件。
但是结果大大超出我的意料。字节流方式复制的文件里面的内容是正确的,相反字符流方式复制里面的内容则出现了乱码。难道是我看资料的时候理解错误了?但是API里面不也是叫处理文本文件的时候用FileReader类和FileWriter类么?
我把代码贴一下,大家帮我看看吧,我试验了好几个文件都是这样的。
  1. import java.io.*;
  2. import java.util.Date;

  3. class TimeTest
  4. {
  5.         public static void main(String[] args)
  6.         {
  7.                 //计算通过字符流实现复制所耗费的时间
  8.                 try{
  9.                         long da1= (new Date()).getTime();   
  10.                         BufferedReader bin = new BufferedReader(new FileReader("E:\\复件 Q.骑士.txt"));//读取文件内容
  11.                         PrintWriter pout = new PrintWriter(new BufferedWriter(new FileWriter("D:\\复件 Q.骑士.txt")));//向文件中写入内容
  12.                         String s1;
  13.                         while((s1 = bin.readLine())!=null)
  14.                         {
  15.                                 pout.write(s1);
  16.                         }
  17.                         bin.close();
  18.                         pout.close();
  19.                    long da2= (new Date()).getTime();  
  20.                    System.out.println("通过字符流实现复制所耗费的时间:"+(da2-da1));
  21.                 }catch(FileNotFoundException e1){
  22.                         e1.printStackTrace();
  23.                 }catch(IOException e2){
  24.                         e2.printStackTrace();
  25.                 }
  26.                 //计算通过字节流实现复制操作所耗费的时间       
  27.                 try
  28.                 {
  29.                         long da3= (new Date()).getTime();
  30.                         FileInputStream fin = new FileInputStream("E:\\Q.骑士.txt");
  31.                         FileOutputStream fout = new FileOutputStream("D:\\Q.骑士.txt");
  32.                         byte[] buffer = new byte[1024*2];
  33.                         int bytelenth = fin.read(buffer);
  34.                         while(bytelenth!=-1)
  35.                         {
  36.                                 fout.write(buffer,0,bytelenth);
  37.                                 bytelenth = fin.read(buffer);
  38.                         }
  39.                         fin.close();
  40.                         fout.close();
  41.                         long da4= (new Date()).getTime();
  42.                         System.out.println("通过字节流实现复制所耗费的时间:"+(da4-da3));
  43.                 }        catch(FileNotFoundException e1){
  44.                         e1.printStackTrace();
  45.                 }catch(IOException e2){
  46.                         e2.printStackTrace();
  47.                         }
  48.         }
  49. }
复制代码
------------TXT里面的内容是下面的这些字符:-------------------------------------
【⊹⊱骑士⊰⊹】

♫ゝ۰» 广场的大钟 铛铛敲了四下⊱
♫ゝ۰» 我跟着鸽子 在小路上溜达⊱
♫ゝ۰» 地铁的出口 有个人弹吉他⊱
♫ゝ۰» 他唱着唱着 眼泪要洒下⊱
♫ゝ۰» 弄堂的门口 大叔卖爆米花⊱
♫ゝ۰» 有堆小朋友 依依呀呀回家⊱
♫ゝ۰» 男生的女生 手捧着一束花⊱
✲⋌⊰⊹完⊹⊱⋋✲
-----------以上内容保存的时候请选择unicode编码的TXT格式----------------------
结果截图:


我觉得问题是出在复制过去的文件的编码上请看下图:字符流复制了文件之后文件的编码变成ANSI的了。

作者: 泮和顺    时间: 2012-3-21 09:01

字节流不能存在编码问题怎么可能有乱码呢
作者: liumeng    时间: 2012-3-21 11:43


        import java.io.*;
        import java.util.Date;

        class TestUnicode
        {
                public static void main(String[] args)
                {
                        //计算通过字符流实现复制所耗费的时间
                        try{
                                long da1= (new Date()).getTime();   
                               FileInputStream fis= new FileInputStream("E:\\复件 Q.骑士.txt");
                                BufferedReader bin = new BufferedReader(new InputStreamReader(fis,"Unicode"));//读取文件内容
                                PrintWriter pout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\复件 Q.骑士.txt"))));//向文件中写入内容
                                String s1;
                                while((s1 = bin.readLine())!=null)
                                {
                                       
                                        pout.write(s1);
                                }
                                bin.close();
                                pout.close();
                           long da2= (new Date()).getTime();  
                           System.out.println("通过字符流实现复制所耗费的时间:"+(da2-da1));
                        }catch(FileNotFoundException e1){
                                e1.printStackTrace();
                        }catch(IOException e2){
                                e2.printStackTrace();
                        }
                        //计算通过字节流实现复制操作所耗费的时间        
                        try
                        {
                                long da3= (new Date()).getTime();
                                FileInputStream fin = new FileInputStream("E:\\Q.骑士.txt");
                                FileOutputStream fout = new FileOutputStream("D:\\Q.骑士.txt");
                                byte[] buffer = new byte[1024*2];
                                int bytelenth = fin.read(buffer);
                                while(bytelenth!=-1)
                                {
                                        fout.write(buffer,0,bytelenth);
                                        bytelenth = fin.read(buffer);
                                }
                                fin.close();
                                fout.close();
                                long da4= (new Date()).getTime();
                                System.out.println("通过字节流实现复制所耗费的时间:"+(da4-da3));
                        }        catch(FileNotFoundException e1){
                                e1.printStackTrace();
                        }catch(IOException e2){
                                e2.printStackTrace();
                                }
                }
        }

作者: 袁冬梅    时间: 2012-3-23 00:43
泮和顺 发表于 2012-3-21 09:01
字节流不能存在编码问题怎么可能有乱码呢

恩,对,是的,字节流不存在编码,这样的话,那么字符流的出现是为了什么呢?不是在编码方面的问题,那么字符流方面速率没有字节流的快,它还有什么优点呢?

那为什么还有人说有些方面字符流的确比字节流有效?是哪些方面呢?
作者: 袁冬梅    时间: 2012-3-23 03:11
liumeng 发表于 2012-3-21 11:43
import java.io.*;
        import java.util.Date;

谢谢你,代码可用。不过需要修改一小点,还有就是我还有一点点小疑问。
修改:PrintWriter pout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\复件 Q.骑士.txt"),"Unicode")));//向文件中写入内容,这里同样需要一个编码集的名称为参数
疑问:为什么我这样做出来了,复制过去的文档内容却不换行呢?这又是什么原理?我看了一下Unicode编码里面的换行符是有编码的呀?难道只是我自己的有问题?对了,如果输出部分不弄上那个编码集的名称参数,复制的文件的特殊符号就出不来,显示问号,所以需要加上那个参数。不过,现在疑惑的是为什么不换行了?你知道是怎么回事么?请帮忙解答一下,谢谢。






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