java 检测文本、文件编码详解编程语言

/** 
     * 默认GB18030 
     */ 
    public static final String detectCharset(byte[] byteArray){ 
        // 建立InputStream 
        ByteArrayInputStream bais = new ByteArrayInputStream(byteArray); 
          
          // 默认编码 
        String utf8 = "UTF-8"; 
          String charset = "GB18030"; 
    
          // 开始检测是否为UTF-8 
          try { 
              // 标记初始位置 
            bais.mark(0); 
    
              // 读取前3字节 
              byte[] first3Bytes = new byte[3]; 
              bais.read(first3Bytes); 
    
              // 如果前三字节为 0xEFBBBF ,则为带签名的UTF-8 
              if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB && first3Bytes[2] == (byte) 0xBF) { 
                return utf8; 
              } 
                
              // 前三字节判定失败,开始检测是否是不带签名的UTF-8 
              // 重置读取位置 
            bais.reset(); 
    
              // 逐字节判定,直到遇到一个UTF-8编码字符 
              byte[] oneByte = new byte[1]; 
              boolean isUtf8 = false; 
              while (-1 != bais.read(oneByte)) { 
                // 如果是ASCII码,跳过 
                if (CharUtils.isAscii((char) oneByte[0])) { 
                    continue; 
                } 
                  
                  // 双字节格式 
                  // 110yyyyy(C0-DF) 10xxxxxx 
                  if ((oneByte[0] & 0xE0) == 0xC0) { 
                    bais.mark(0); 
                      byte[] nextOneByte = new byte[1]; 
                      if (bais.available() >= 1 && -1 != bais.read(nextOneByte)) { 
                          if ((nextOneByte[0] & 0xC0) == 0x80) { 
    
                              // 是GBK双字节重叠部分?暂时当GBK处理,中文系统下,GBK默认编码,UTF-8不常见 
                              // 双字节,第一个字节的值从0x81到0xFE,第二个字节的值从0x40到0xFE(不包括0x7F) 
                              int oneByteInt = oneByte[0] & 0xff; 
                              int nextOneByteInt = nextOneByte[0] & 0xff; 
                              if ( 
                                    ((0x81 & 0xff) < = oneByteInt && oneByteInt <= (0xFE & 0xff)) 
                                      && ((0x40 & 0xff) <= nextOneByteInt && nextOneByteInt <= (0xfe & 0xff)) 
                                      && (nextOneByte[0] != 0x7F) 
                                  ) { 
                                  continue; 
                              } 
    
                              // 非GBK重叠部分,归于UTF-8 
                              isUtf8 = true; 
                              break; 
                          } 
                          bais.reset(); 
                      } 
                  } 
    
                  // 三字节格式 
                  // 1110xxxx(E0-EF) 10xxxxxx 10xxxxxx 
                  if ((oneByte[0] & 0xF0) == 0xE0) { 
                      byte[] twoByte = new byte[2]; 
                      bais.mark(0); 
                      if (bais.available() >= 2 && -1 != bais.read(twoByte)) { 
                          if (((twoByte[0] & 0xC0) == 0x80) && ((twoByte[1] & 0xC0) == 0x80)) { 
                              isUtf8 = true; 
                              break; 
                          } 
                          bais.reset(); 
                      } 
                  } 
    
                  // 四字节格式 
                  // 11110www(F0-F7) 10xxxxxx 10xxxxxx 10xxxxxx 
                  if ((oneByte[0] & 0xF8) == 0xF0) { 
                      byte[] threeByte = new byte[3]; 
                      bais.mark(0); 
                      if (bais.available() >= 3 && -1 != bais.read(threeByte)) { 
                          if (((threeByte[0] & 0xC0) == 0x80) && ((threeByte[1] & 0xC0) == 0x80) 
                                  && ((threeByte[2] & 0xC0) == 0x80)) { 
                              isUtf8 = true; 
                              break; 
                          } 
                          bais.reset(); 
                      } 
                  } 
    
                  // 五字节格式 
                  // 111110xx(F8-FB) 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
                  if ((oneByte[0] & 0xFC) == 0xF8) { 
                      byte[] fourByte = new byte[4]; 
                      bais.mark(0); 
                      if (bais.available() >= 4 && -1 != bais.read(fourByte)) { 
                          if (((fourByte[0] & 0xC0) == 0x80) && ((fourByte[1] & 0xC0) == 0x80) 
                                  && ((fourByte[2] & 0xC0) == 0x80) 
                                  && ((fourByte[3] & 0xC0) == 0x80)) { 
                              isUtf8 = true; 
                              break; 
                          } 
                          bais.reset(); 
                      } 
                  } 
    
                  // 六字节格式 
                  // 1111110x(FC-FD) 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
                  if ((oneByte[0] & 0xFE) == 0xFC) { 
                      byte[] fiveByte = new byte[5]; 
                      bais.mark(0); 
                      if (bais.available() >= 5 && -1 != bais.read(fiveByte)) { 
                          if (((fiveByte[0] & 0xC0) == 0x80) && ((fiveByte[1] & 0xC0) == 0x80) 
                                  && ((fiveByte[2] & 0xC0) == 0x80) 
                                  && ((fiveByte[3] & 0xC0) == 0x80) 
                                  && ((fiveByte[4] & 0xC0) == 0x80)) { 
                              isUtf8 = true; 
                              break; 
                          } 
                          bais.reset(); 
                      } 
                  } 
              } 
    
              // 依据标志位设定返回值 
              if (isUtf8) { 
                  return utf8; 
              } 
          } catch (IOException e) { 
          }  
    
          // 返回字符编码格式 
          return charset; 
      }

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/10368.html

(0)
上一篇 2021年7月19日 10:11
下一篇 2021年7月19日 10:11

相关推荐

发表回复

登录后才能评论