一.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. 洛谷P3763 [TJOI2017]DNA(后缀数组 RMQ)

    题意 题目链接 Sol 这题打死我也不会想到后缀数组的,应该会全程想AC自动机之类的吧 但知道这题能用后缀数组做之后应该就不是那么难了 首先把\(S\)和\(S0\)拼到一起跑,求出Height数组 ...

  2. Vijos / 题库 / 输油管道问题

    背景 想念car的GF,car就出了道水题! 描述 某石油公司计划建造一条由东向西的主输油管道.该管道要穿过一个有n 口油井的油田.从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连.如果 ...

  3. JS实现小图放大轮播效果

    JS实现小图放大轮播页面效果入下(图片为优行商旅页面照片): 实现效果:图片自动轮播,鼠标移入停止,移出继续轮播点击下方小图可以实现切换 步骤一:建立HTML布局,具体如下: <body> ...

  4. html打造动画【系列4】哆啦A梦

    我相信每个人的童年都有一个哆啦a梦,一个小小的肚皮里装满了不可思议的哆啦a梦,一个在你无助伤心的时候陪在你身边的哆啦a梦,一个陪你胡思乱想陪你吃铜锣烧的哆啦a梦~今天我们就来画一个我们心中的哆啦a梦吧 ...

  5. Flex 加载pdf

    如果想要在flex加载pdf,虽然pdf格式是开源的,但是自己去解析太麻烦了,pdf还要分页之类的,现在网上各种文档上传可以在线看很多都是pdf,当然也有word,excel之类,其实很多都是转了sw ...

  6. 公司网络问题 & Caused by: org.gradle.internal.resource.transport.http.HttpRequestException

    问题 公司网络问题,总是无法成功下载库,回到家就可以. Caused by: org.gradle.internal.resource.transport.http.HttpRequestExcept ...

  7. Fragment初探

    Fragment允许将Activity拆分成多个完全独立封装的可重用的组件,每个组件有它自己的生命周期和UI布局.Fragment最大的优点是为不同屏幕大小创建灵活的UI.每个Fragment都是独立 ...

  8. 3.Bootstrap CSS 概述

    1.HTML 5 文档类型(Doctype) Bootstrap 使用了一些 HTML5 元素和 CSS 属性.为了让这些正常工作,您需要使用 HTML5 文档类型(Doctype). 因此,请在使用 ...

  9. MySQL经典错误

    本文目录: Top 1:Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行)Top 2:(主从复制报错类型)Top 3:MySQL安装过程中的报错Top 4:数 ...

  10. fiddler抓取APP请求

    必备环境: 1.电脑上已经安装fiddler 2.手机和电脑在同一局域网 设置:Fiddler>Tools>Fiddler Options>Connections 勾选Allow r ...