zoukankan      html  css  js  c++  java
  • java和unicode

    故事是这样的,那天和同事讨论上传txt文件,如何能防止文件乱码,其间引出了如下问题: 

       
    • 1.如何防止上传文件乱码(无论任何语言). 
    • 2.用byte array&utf-8构造string,java如何判断几个byte一个中文字符. 
    • 3.utf-8和unicode的区别. 
    • 4.一个utf-8 string有几个char,几个byte?

      随着这些问题的解决,对java和unicode,utf-8之间的关系有了更深层的认识. 


    如何防止上传文件乱码(无论任何语言). 
      为了支持i18n,我们必须要求上传文件的编码是utf-8或unicode,否则无法实现全语言的支持.utf-8的文件开头会有EF BB BF标志。 

    用byte array&utf-8构造string,java如何判断几个byte一个中文字符. 
      因utf-8是变长编码,所以有些字符会是一个字节(如:ascii),有些会是3个(如:中文), 
    但在用byte array构造string时,jvm是如何判断以几个字节为一组来构造呢? 
      原来utf-8编码本身有标志可以判断,每个字符的第一个byte前几位是标示位10*,110*,1110*,11110*,其中1的个数代表这个字符有几个字节。 

    utf-8和unicode的区别. 
      unicode是定长编码,每个字符都是2 byte,所以在存储ascii时会浪费一个byte的空间。而utf-8是变长unicode编码,在unicode编码基础上进行变长,在存储ascii时只占用一个byte.存储中文时占用3 byte. 

    一个utf-8 string有几个char,几个byte? 
    Java代码  收藏代码
    1. String s = "中国";     
    2. byte[] b = s.getBytes("utf-8");  
    3. String s_utf8 = new String(b,"utf-8");  
    4. System.out.println(s_utf8.getBytes("utf-8").length);  
    5. System.out.println(s_utf8.toCharArray().length);  

    结果是: 
        6 
        2 
    按照上面的结果看好像一个char是3 byte,但java中一个char是2 byte,为什么? 
    其实java中无论什么字符集string都会以unicode编码来存储,所以每个char都是一个 
    unicode编码占两个byte。 
    Java代码  收藏代码
    1. import java.io.UnsupportedEncodingException;  
    2.   
    3.   
    4. public class TestUtf8File {  
    5.   
    6.   /** 
    7.    * @param args 
    8.    * @throws UnsupportedEncodingException  
    9.    */  
    10.   public static void main(String[] args) throws UnsupportedEncodingException {  
    11.   
    12.     String s = "中国人";     
    13.     byte[] b = s.getBytes("utf-8");  
    14.     String s_utf8 = new String(b,"utf-8");  
    15.     System.out.println(s_utf8.getBytes("utf-8").length);  
    16.     System.out.println("utf-8 bytes:");  
    17.     printByteArray(s_utf8.getBytes("utf-8"));  
    18.     System.out.println("chars:");  
    19.     printCharArray(s_utf8.toCharArray());  
    20.       
    21.     byte[] unicodeb= s.getBytes("unicode");  
    22.     String s_unidode = new String(unicodeb,"unicode");  
    23.     System.out.println("unicode bytes:");  
    24.     printByteArray(s_unidode.getBytes("unicode"));  
    25.   
    26.   }  
    27.     
    28.   private static void printByteArray(byte[] b){  
    29.     for(int i = 0;i < b.length; i++){  
    30.       System.out.println((Integer.toString(b[i],16)));  
    31.         
    32.     }  
    33.   }  
    34.     
    35.   private static void printCharArray(char[] c){  
    36.     for(int i = 0;i < c.length; i++){  
    37.       System.out.println(Integer.toString((byte)(c[i]>>8),16));  
    38.       System.out.println(Integer.toString((byte)(c[i]&0xff),16));  
    39.         
    40.     }  
    41.   }  
    42.   
    43. }  

    output: 

    utf-8 bytes: 
    -1c 
    -48 
    -53 
    -1b 
    -65 
    -43 
    -1c 
    -46 
    -46 
    chars: 
    4e 
    2d 
    56 
    -3 
    4e 
    -46 
    unicode bytes: 
    -2 
    -1 
    4e 
    2d 
    56 
    -3 
    4e 
    -46 


    -2 -1(FE FF)是unicode big endian标志 
    fe ff:big endian 
    ff fe: no big endian
  • 相关阅读:
    Atitti 图像处理 图像混合 图像叠加 blend 原理与实现
    Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途
    Atitit 图像处理 灰度图片 灰度化的原理与实现
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结
    Atitit 实现java的linq 以及与stream api的比较
    Atitit attilax在自然语言处理领域的成果
    Atitit 图像处理 常用8大滤镜效果 Jhlabs 图像处理类库 java常用图像处理类库
    Atitit 图像处理--图像分类 模式识别 肤色检测识别原理 与attilax的实践总结
    Atitit apache 和guava的反射工具
    atitit。企业的价值观 员工第一 vs 客户第一.docx
  • 原文地址:https://www.cnblogs.com/yht520/p/3589642.html
Copyright © 2011-2022 走看看