一.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
把上面的代码复制进去就可以了,这个在线的便宜工具只能识别一些简单的类,像字节流那些还是不能识别的。

共勉:别忘了你是第一名

Java byte数据转换和处理总结的更多相关文章

  1. 【转】java byte转long、double、float、int、short,或者long、double、float、int、short转byte

    原文网址:http://www.xuebuyuan.com/988752.html java byte与其他数据类型的转换主要用于二进制数据的编码和解码,主要用于网络传输,读写二进制文件,java和c ...

  2. java byte【】数组与文件读写(增加新功能)

    今天在测试直接写的文章: java byte[]数组与文件读写 时,想调用FileHelper类对字节数组以追加的方式写文件,结果无论怎样竟然数据录入不全,重新看了下文件的追加模式,提供了两种方式: ...

  3. Java Byte取值范围

    Java Byte 的取值范围大家都知道(-128 ~ 127),那么-128 和 127 这两个数是怎么计算的呢? #大学知识回顾: 概念:负数的补码是该 数 绝 对 值 的 原 码 按 位 取 反 ...

  4. java byte数组与String互转

      java byte数组与String互转 CreationTime--2018年7月6日14点53分 Author:Marydon 1.String-->byte[] 方法:使用String ...

  5. java byte数组与16进制间的相互转换

      java byte数组与16进制间的相互转换 CreationTime--2018年6月11日15点34分 Author:Marydon 1.准备工作 import java.util.Array ...

  6. Java byte类型转换成int类型时需要 & 0XFF的原因

    Java byte类型转换成int类型时需要 & 0XFF的原因 假设有byte b  = -1; 那么b的二进制是:1111 1111. 如果将b直接转换为int类型,那么二进制是 1111 ...

  7. java byte to hex

    String str; byte[] bs = null; bs =str.getBytes(); bs =str.getBytes("utf-8") java  byte to ...

  8. java byte中存大于0x7E的十六进制数

    在做一个Android app和arm板子交互的程序中,遇到一个问题,Java byte中无法直接存储大于0x7E的十六进制,但是C语言却可以. 出现这个状况的原因是:Java中是byte存储的是有符 ...

  9. Java byte[] 转C# byte[]

    byte(C# 参考) byte 关键字代表一种整型,该类型按下表所示存储值: 类型 范围 大小 .NET Framework 类型 byte 0 到 255 无符号 8 位整数 Byte 参考msd ...

随机推荐

  1. vue-router初涉

    概念: vue-router: vue官方路由插件. 路由: 指单页面应用的路径管理系统.在vue中都是单页应用,相当于只有一个index.html页面,所以无法使用<a>标签,我们使用路 ...

  2. Python 批量修改文件名并移动文件到指定目录

    # -*- coding: utf-8 -*- import os, sys,re,shutil from nt import chdir #读取中文路径 u'' path=u"D:\\zh ...

  3. Java快速入门-04-Java.util包简单总结

    学Java的程序员,lang包和util包最好是要过一遍的. 建议大家都序下载一个离线版开发文档,查阅非常方便,我给大家提供一个中文版 jdk1.8 离线文档,查看:JAVA - JDK 1.8 AP ...

  4. linux下close 掉socket 之后 阻塞的recv 不会立即返回

    转载自:http://www.cnblogs.com/wainiwann/p/3942203.html 在开发的一个基于rtmp聊天的程序时发现了一个很奇怪的现象. 在windows下当我们执行 cl ...

  5. Effective C++(6) 如何拒绝编译器的自动生成函数

    问题聚焦: 如果不希望class支持某一成员函数,那么不声明和定义它就可以了,但是这一策略对与拷贝构造函数和重载赋值操作符并不起作用. 因为如果不声明它们,那么当尝试调用它们的时候,编译器会为你声明和 ...

  6. 自动化测试全套流程(一)-搭建Jenkins环境

    前提 既然要做自动化测试,那我们就做得彻底一些,将整套系统部署在Linux服务器上,在搭建Jenkins环境之前,我已经通过VirtualBox安装了一个CentOS的服务器,搭建Jenkins是基于 ...

  7. Android sdk manager 更新 5.0 太难了,终于解决

    由于众所周知的原因,必须在hosts中增加一些网址对应,才可以更新 203.208.46.146 www.google.com 203.208.46.1 plus.google.com 203.208 ...

  8. December 19th 2016 Week 52nd Sunday

    Truth and roses have thorns about them. 真理和玫瑰,身边都有刺. Either truth or roses, they all have thorns aro ...

  9. python中的装饰

    在面向对象(OOP)的设计模式中,decorator被称为装饰模式.OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator ...

  10. A blog about Core Animation and other iOS graphics framework

    A blog about Core Animation and other iOS graphics frameworks. https://www.calayer.com/