当前位置: 技术问答>java相关
高手请指教:为什么不行!!!!!
来源: 互联网 发布时间:2014-12-28
本文导语: 我编写了一小段代码:用于分割文件。 但是我用FileReader读写word文档时居然读少了若干字节(而读写txt型文件没有问题)。 后来发现,FileReader在读16进制FE AA FF 11时居然读出了65533 65533,然后写入文件就写成了3F 3F...
我编写了一小段代码:用于分割文件。
但是我用FileReader读写word文档时居然读少了若干字节(而读写txt型文件没有问题)。
后来发现,FileReader在读16进制FE AA FF 11时居然读出了65533 65533,然后写入文件就写成了3F 3F.
按照Thinking in java的说法,FileReader是为了取代FileInputStream而产生的,为什么会出错,还是我的代码有问题?
------------------------------------------------
高手请指教!
但是我用FileReader读写word文档时居然读少了若干字节(而读写txt型文件没有问题)。
后来发现,FileReader在读16进制FE AA FF 11时居然读出了65533 65533,然后写入文件就写成了3F 3F.
按照Thinking in java的说法,FileReader是为了取代FileInputStream而产生的,为什么会出错,还是我的代码有问题?
------------------------------------------------
高手请指教!
|
首先,Java 1.2以上版本引入Reader,Writer 目的不是为了让你用它来读一个字节流的文件!:) 它的目的是为了让你可以使用它来读MBCS(Multi-Bytes Code System)的“文本”文件,因为新引入的Reader,Writer可以读入Unicode的Character! 也就是说,如果你使用了任何一种有效的编码(汉字,阿拉伯,等等)来写一个“文本”文件,用Reader和Writer都可以正确地使用,不会象InputStream, OutputStream处理“文本”时可能会在字符中间中断从而产生错误,因为它们Stream设计是来处理字节流的。同样,这也解释了为什么你用InputStream可以正确地处理任何面向字节的处理。
接着解释为什么你的FE AA 或 FF 11会转换成 65533 65533 => 3f 3f,因为Java试图将你的DOC文件当作一个Unicode文本文件来处理,但是,FE AA与 FF 11在UTF-8标准中是不存在的字符(Character),而Unicode规定在这种情况下将它转成"?",也即 3F。在Java中,内部是使用Unicode标准的。
UTF-8标准就是Java在任何缺省平台上使用的Unicode标准,你可以去http://www.unicode.org 参考详细的标准,我简单介绍UTF-8如下:
在Unicode中编码为 0000 - 007F 的 UTF 中编码形式为: 0xxxxxxx
在Unicode中编码为 0080 - 07FF 的 UTF 中编码形式为: 110xxxxx 10xxxxxx
在Unicode中编码为 0000 - 007F 的 UTF 中编码形式为: 1110xxxx 10xxxxxx 10xxxxxx
简单地可见,不存在以FF或FE开头的任何UTF-8字符编码!
也许有人想问,照这么说,GB2313或GBK之类的文本文件似乎也有编码不符合UTF-8标准,为什么可以转换呢?但请仔细看看JavaDOC中对FileReader的说明:"这是一个读字符文件的类!这个类的构造方法假定默认的字符编码和字节缓冲区容量是正确的,如果你需要改变这些值,要通过FileInputStream构造一个InputStreamReader!"
在GB2312平台上,它默认的字符编码是GB2312,这是正确的,在此情况下,JAVA会作GB2312=》UTF-8的转换,结果也是正确的!但你的DOC文件的默认编码未指定时,是会采用UTF-8的。
所以,要处理象DOC或XLS之类的二进制文件时,还是要使用Stream!而不是什么Reader,Writer!
接着解释为什么你的FE AA 或 FF 11会转换成 65533 65533 => 3f 3f,因为Java试图将你的DOC文件当作一个Unicode文本文件来处理,但是,FE AA与 FF 11在UTF-8标准中是不存在的字符(Character),而Unicode规定在这种情况下将它转成"?",也即 3F。在Java中,内部是使用Unicode标准的。
UTF-8标准就是Java在任何缺省平台上使用的Unicode标准,你可以去http://www.unicode.org 参考详细的标准,我简单介绍UTF-8如下:
在Unicode中编码为 0000 - 007F 的 UTF 中编码形式为: 0xxxxxxx
在Unicode中编码为 0080 - 07FF 的 UTF 中编码形式为: 110xxxxx 10xxxxxx
在Unicode中编码为 0000 - 007F 的 UTF 中编码形式为: 1110xxxx 10xxxxxx 10xxxxxx
简单地可见,不存在以FF或FE开头的任何UTF-8字符编码!
也许有人想问,照这么说,GB2313或GBK之类的文本文件似乎也有编码不符合UTF-8标准,为什么可以转换呢?但请仔细看看JavaDOC中对FileReader的说明:"这是一个读字符文件的类!这个类的构造方法假定默认的字符编码和字节缓冲区容量是正确的,如果你需要改变这些值,要通过FileInputStream构造一个InputStreamReader!"
在GB2312平台上,它默认的字符编码是GB2312,这是正确的,在此情况下,JAVA会作GB2312=》UTF-8的转换,结果也是正确的!但你的DOC文件的默认编码未指定时,是会采用UTF-8的。
所以,要处理象DOC或XLS之类的二进制文件时,还是要使用Stream!而不是什么Reader,Writer!
|
用BufferedReader+FileInputStream