zoukankan      html  css  js  c++  java
  • Java byte数据转换和处理总结

    一.byte和int相互转换的方法

    java程序或Android程序的socket数据传输,都是通过byte数组,但是int类型是4个byte组成的,如何把一个整形int转换成byte数组,同时如何把一个长度为4的byte数组转换为int类型。

    /** 
     * int到byte[] 
     * @param i 
     * @return 
     */  
    public static byte[] intToByteArray(int i) {  
        byte[] result = new byte[4];  
        // 由高位到低位  
        result[0] = (byte) ((i >> 24) & 0xFF);  
        result[1] = (byte) ((i >> 16) & 0xFF);  
        result[2] = (byte) ((i >> 8) & 0xFF);  
        result[3] = (byte) (i & 0xFF);  
        return result;  
    }  
    
    /** 
     * byte[]转int 
     * @param bytes 
     * @return 
     */  
    public static int byteArrayToInt(byte[] bytes) {  
        int value = 0;  
        // 由高位到低位  
        for (int i = 0; i < 4; i++) {  
            int shift = (4 - 1 - i) * 8;  
            value += (bytes[i] & 0x000000FF) << shift;// 往高位游  
        }  
        return value;  
    }  
    
    
    //测试数据
    public static void main(String[] args) {  
        byte[] b = intToByteArray(128);  
        System.out.println(Arrays.toString(b));//打印byte的每一个字节  
    
        int i = byteArrayToInt(b);  
        System.out.println(i);  //打印byte转变为Int后的数据 
    }   

    二.byte和String相互转换

    上面只说到byte和int的相互转换,其实呢byte和String也是可以相互转换的,毕竟Socket通信也是需要传递字符串的。 
    其他的方面,char和long、float这些数据都是可以转换为byte的,但是实际应用场合比较少。

    //String 和byte相互转换的示例
    
        String string = "hello 世界小姐";
    
            byte[] bytes = string.getBytes();//获得byte数组
    
            System.out.println("bytes-->" + Arrays.toString(bytes));//打印byte数组
    
            System.out.println("string-->" + new String(bytes));//获得byte数组转换来的String数据,并打印

    上面第一第二都是byte数组和其他数据相互转换,其实也可以通过流的来获取字节,传递过去后再把字节放到流里面去,解封出来,但是那样还是太麻烦的!不建议做。

    三.byte占用字节大小详解

    在Java中一共有8种基本数据类型,其中有4种整型,2种浮点类型,1种用于表示Unicode编码的字符单元的字符类型和1种用于表示真值的boolean类型。(一个字节等于8个bit)

    1.整型
    类型                  存储需求                   bit               取值范围                备注
    int                       4字节                      4*8                  很大
    short                   2字节                      2*8         -32768~32767
    long                    8字节                      8*8                 非常大
    byte                    1字节                      1*8             -128~127

    2.浮点型

    类型                存储需求                   bit                    取值范围             备注
    float                   4字节                     4*8                       很大           float类型的数值有一个后缀F(例如:3.14F)
    double               8字节                     8*8                      非常大        没有后缀F的浮点数值(如3.14)默认为double类型

    3.char类型

    类型                 存储需求                  bit                   取值范围              备注
    char                   2字节                      2*8             -32768~32767

    4.boolean类型

    类型                 存储需求                  bit                   取值范围              备注
    boolean              1字节                    1*8                 false、true

    四.String与byte[]字节数组中文转换乱码问题

    在Java中,String.getBytes(String decode)方法会根据指定的decode编码返回某字符串在该编码下的byte数组表示,如

    byte[] b_gbk = “中”.getBytes(“GBK”);

    byte[] b_utf8 = “中”.getBytes(“UTF-8”);

    byte[] b_iso88591 = “中”.getBytes(“ISO8859-1”);

    byte[] b_unicode = “中”.getBytes(“unicode”);

    将分别返回“中”这个汉字在GBK、UTF-8和ISO8859-1编码下的byte数组表示,
    此时b_gbk的长度为2,b_utf8的长度为3,b_iso88591的长度为1,
    b_unicode 的长度为4(系统的的unicode采用的是big-endian就是前面是两个字节来表示这个的,unicode采用的都是两个字节编码,所以后面是4个字节 )。

    而与getBytes相对的,可以通过new String(byte[], decode)的方式来还原这个“中”字时,这个new String(byte[], decode)实际是使用decode指定的编码来将byte[]解析成字符串。

    String s_gbk = new String(b_gbk,”GBK”);

    String s_utf8 = new String(b_utf8,”UTF-8”);

    String s_iso88591 = new String(b_iso88591,”ISO8859-1”);

    通过打印s_gbk、s_utf8和s_iso88591,会发现,s_gbk和s_utf8都是“中”,而只有s_iso88591是一个不认识的字符,为什么使用ISO8859-1编码再组合之后,
    无法还原“中”字呢,其实原因很简单,因为ISO8859-1编码的编码表中,
    根本就没有包含汉字字符,当然也就无法通过”中”.getBytes(“ISO8859-1”);来得到正确的“中”字在ISO8859-1中的编码值了,所以再通过new String()来还原就无从谈起了。

    因此,通过String.getBytes(String decode)方法来得到byte[]时,一定要确定decode的编码表中确实存在String表示的码值,这样得到的byte[]数组才能正确被还原。

    有时候,为了让中文字符适应某些特殊要求(如http header头要求其内容必须为iso8859-1 编码),可能会通过将中文字符按照字节方式来编码的情况,
    如 String s_iso88591 = new String(“中”.getBytes(“UTF-8”),”ISO8859-1”),这样得到的s_iso8859-1字符串实际是三个在ISO8859-1中的字符,
    在将这些字符传递到目的地后,目的地程序再通过相反的方式String s_utf8 = new String(s_iso88591.getBytes(“ISO8859-1”),”UTF-8”)来得到正确的中文汉字“中”。
    这样就既保证了遵守协议规定、也支持中文。

    String的getBytes()方法是得到一个字串的字节数组,这是众所周知的。但特别要注意的是,本方法将返回该操作系统默认的编码格式的字节数组。
    如果你在使用这个方法时不考虑到这一点,你会发现在一个平台上运行. 良好的系统,放到另外一台机器后会产生意想不到的问题。

    对也String来说,一个英文字符固定占1个字节,而中文字符占2个(GBK编码)或3个(UTF-8编码)字节。

    五.byte字节其他的知识

    两个字节能不能表示一个int呢?

    其实也是可以的,就是有一些坑会在里面! 
    代码:

       int a = 100;
       byte b1 = (byte) ((a >> 8) & 0xFF);   //高8位
       byte b2 = (byte) (a & 0xFF); //低8位
       System.out.println(a+"-->"+(b1)+(b2) );
    
    
       int value = 0;
       value += (b1 & 0xFF) << 8;// 往高位游
       value += (b2 & 0xFF);//
       System.out.println("value=" + value);

    如果a的数值在0到32767之内都是正常的。

    正常情况是没有问题的,像一般字符串的长度用两个字节的byte和int相互转换来表示长度,但是如果是负数就不可以用两个字节byte来和int相互转换了。
    因为如果是负数的话符号位就是1了,左移和右移有很大想差别。
    像会出现负数的情况还是要使用四个byte来和int做相互转换传递数据。

    在线测试一下
    如果想简单验证也可以使用在线java编译工具,测试一下:
    http://www.runoob.com/try/runcode.php?filename=HelloWorld&type=java
    把上面的代码复制进去就可以了,这个在线的便宜工具只能识别一些简单的类,像字节流那些还是不能识别的。

    共勉:别忘了你是第一名

  • 相关阅读:
    20145305 《信息安全系统设计基础》第10周学习总结
    20145305 《信息安全系统设计基础》实验五 网络通信
    20145305 《信息安全系统设计基础》实验四 驱动程序设计
    20145304 《信息安全系统设计基础》课程总结
    20145304 《信息安全系统设计基础》第十四周学习总结
    计算机系统要素
    20145304 《信息安全系统设计基础》第十三周学习总结
    20145304 《信息安全系统设计基础》第十二周学习总结
    GDB调试汇编堆栈
    20145304 20145315 《信息安全系统设计基础》 实验五 网络通信
  • 原文地址:https://www.cnblogs.com/HappySimon/p/9911682.html
Copyright © 2011-2022 走看看