识别文件编码.docVIP

  • 41
  • 0
  • 约6千字
  • 约 8页
  • 2018-08-02 发布于山西
  • 举报
识别文件编码

根据不同编码的特点和标志,对一个文本文件判断编码方法如下 1 . UTF7 所有字节的内容不会大于127,也就是不大于HFF 2 . UTF8 起始三个字节为EF BB BF 3 . UTF16BigEndian 起始三个字节为FE FF 4 . UTF16SmallEndian 起始三个字节为FF FE 注: BigEndian 和SmallEndian 表示存储方式的高位在前或者低位 ? ?在前,高位在前叫BigEndian 反之叫SmallEndian 在经过一些测试之后,研究了一个解决方案。 考虑如下文件输入流的代码, FileInputStream fis = null; InputStreamReader isr = null; BufferedReader br = null; File f = new File(fn); fis = new FileInputStream(f); isr = new InputStreamReader(fis, UTF-8); br = new BufferedReader(isr); 推测执行原理如下,(都是根据测试结果的猜测) 1。fis 根据文件的保存编码来采用不同的编码读取文件。读取结果为byte[] 2.isr设定的话,那么根据isr设定的编码来读取文件,如果不设定,那么编码采用系统默认编码 ansi(window-31j,shift_jis) 3。br.readline,将isr的结果组合为String,如果isr没有设定编码,那么组合String时采用的编码为系统默认编码 ansi(window-31j,shift_jis),如果isr设定了编码,那么采用isr设定好的编码。 4。new string(byte[],encode) 根据指定编码生成string,如果不指定,采用系统默认编码。系统默认编码 ansi 5。string.getbyte(encode) 从String根据特定的编码取得byte[] 问题出在第1步,第一步fis因为读取文件的时候,调用的是native,也就是系统(windows系统)的东西,他用了系统的东西,系统的这个东西作了编码判断,但是因为他调用的是native的东西,这个判定结果没有返回给java,导致java里面isr,br没有办法跟fis协调一致,isr,br只能采用系统默认编码 ansi(window-31j,shift_jis),而不是采用fis的判定结果来读取文件。 这导致了,当文件使用ansi编码保存的时候,默认编码跟fis判定结果一致,不会出任何问题。 当文件使用了utf-8编码的时候,默认编码ansi,跟fis判定结果utf-8不一致,fis采用uft-8编码读取出文件内容,而后,br.readline采用系统默认编码把UTF-8编码对应的byte[]组合成了ansi编码对应的字符串,就产生了乱码。 我在网络以及java api里面查找了一下,没有找到判定文件保存编码的方法。推论:因为java是调用了native的方法来实际读取文件的,判定在native里面完成,但是没有把判定结果公开给我们程序员。 另有一个测试结果的推论,英文字符在任何编码下面读取出来的byte[]都是一样的。因为我们才用任何编码都不会出现英文字符乱码的问题,所以大多数时候这个判定对我们没有影响,这里不讨论特殊情况下因为这个原因造成的影响。 根据以上推论,考虑如下解决问题的思路, 1。通过fis来读取文件,这个时候读取来的byte[]根据文件的保存格式是不同的。fis会自动判断处理。 2。通过br来读取文件。代码示例如下: private static void readTest(String fn){ BufferedReader br = null; InputStreamReader isr = null; FileInputStream fis = null; try{ File f = new File(fn); fis = new FileInputStream(f); isr = new InputStreamReader(fis, UTF-8); br = new BufferedReader(isr); String s = null;

文档评论(0)

1亿VIP精品文档

相关文档