int与byte那些事你确定知道?

17 篇文章 0 订阅

前言

最近在做一个远程屏幕共享软件,功能非常单一,只能通过Android端查看电脑的实时屏幕,一开始做法是电脑端不停捕获当前屏幕截图,压缩后上传到服务器,Android不停的刷新,但是结果有点不尽人意,效果太差了。其中并没有将捕获的屏幕保存成jpg,然后发送,而是直接将BufferedImage转换成 byte[]发送,当然服务器也没有存成文件,也是使用byte[]存最新的屏幕数据,Android通过给定接口将byte[]转换成图像。

这里面有个将InputStream中的数据转换成BufferedImage的逻辑,我们可以使用 ImageIO这个类。
在这里插入图片描述
但是经过测试,JPEGCodec这个类似乎更好一些,但不知是不是如此,我不太确定。(ImageIO出现过错误,反而JPEGCodec却没有),但是注意的是,JPEGCodec并不属于Java APIs的一部。
在这里插入图片描述

另外内存也占的太多,这归根到底,是自己不会高深算法,哎。

于是也企图研究一下,后来通过Socket来完成,这回延时也比较低,但是是属于直连的形式,也就是手机通过Socket直接怼到电脑,电脑端不停的发送屏幕数据,可能在同一个局域网,速度也比较快。另外经过优化,内存、CPU使用率都不是很高,窗口在拖动时Android端也差不多能流畅的显示。

但是要做的并不是如此,不想只限制在局域网中,所以,我需要一个数据中转服务器。

电脑和Android通过Socket连接到服务器,服务器收到电脑发送的数据后传递给所有Android端。恩,大致是这样。
在这里插入图片描述

但是也遇到很多问题,如我要自定义一个格式,要将int转byte[],byte[]在转int,我想有必要记录下转换过程。

int转byte

在java中,int为8字节,二进制为32位,范围在2147483648——2147483647之间,而byte在-128~127之间,那int转byte就有些小计算了,大桶不可能完全放进小桶内,那么这样转换逼不得已要把大桶敲碎,把一小块放进小桶内,这会导致什么?当然是转换后的值不一定是原来的值了。

下面这个输出的byteValue也等于intValue,这是因为还没有越界,byte还能容纳。

 public static void main(String[] args) {
     int intValue =123;
     byte byteValue =(byte)intValue;
     System.out.println(byteValue);//123
 }

好,再看下一个,这回输出为-69,想知道内部是怎么转换的吗?

 public static void main(String[] args) {
     int intValue =187;
     
     byte byteValue =(byte)intValue;
     System.out.println(byteValue);
 }

在上面我们说过,要把大桶敲碎,在装进去,在这里,我要就要把int敲碎,要敲那部分呢?当然是敲他二进制的后8位。(此时我们要明白Java是采用补码存储整数)

首先把187转换为二进制。

00000000 00000000 00000000 10111011

然后敲出他的后8位,(补码表示的时候第一位是符号位,0为正数,1为负数,剩余是他的数值部分),所以他是一个负数,这也是为什么输出负数的原因。

1011 1011

然后将他的数值部分取反后+1(符号位不变)。

011 1011(7位数值部分)
100 0100(7位数值部分)  //取反
100 0101(7位数值部分)  //+1

然后直接算100 0101的十进制为69,又因为最高位是1,所以他是负数,为-69,这里要注意的是,不能算符号位,如果最终也算符号位的话,那么基本数据类型的范围将不是现在这样。

int转byte[]

我们知道了int转byte的方法,那么转byte[]其实就是把4个8位分别放入到4个字节中。

举个例子,1154的二进制为以下。

00000000 00000000 00000100 10000010

而现在有四个byte,也就是byte[4]。
第一个byte为00000000,最终值为0
第二个byte为00000000,最终值为0
第三个byte为00000100,最终值为4
第四个byte为10000010,最终值为-126(最高位为1,为负数,数值部分取反+1)

那么我们来测试一下,是不是这样

public static void main(String[] args) {
    ByteBuffer byteBuffer=ByteBuffer.allocate(4);
    byteBuffer.putInt(1154);
    byteBuffer.flip();
    byte[] dst =new byte[4];
    byteBuffer.get(dst);
    for (byte b : dst) {
        System.out.println(b);
    }
}

输出结果
在这里插入图片描述

byte[]转int

在举个例子,现在byte[4]中的值分别是以下值

byte[0]= 0
byte[1]= 21
byte[2]=-12
byte[3]=-89

+21的补码00010101。
-12的补码11110100.
-89的补码10100111.

最终二进制为00000000 00010101(+21) 11110100(-12) 10100111(-89),为1438887

再来验证一下。

 public static void main(String[] args) {
     byte[]dst=   new byte[]{0,21,-12,-89};
     ByteBuffer byteBuffer=ByteBuffer.wrap(dst);
     System.out.println(byteBuffer.getInt());
 }

输出
在这里插入图片描述

在举个负数例子.

byte[0]= -78
byte[1]= 0
byte[2]=0
byte[3]=46

-78的补码为10110010。
+46的补码为00101110。
最终10110010000000000000000000101110,由于最高位是1,是个负数,则将后面的数值取反+1为11001101111111111111111111010010,转换成十进制就是-1308622802。
验证。

 public static void main(String[] args) {
     byte[]dst=   new byte[]{-78,0,0,46};
     ByteBuffer byteBuffer=ByteBuffer.wrap(dst);
     System.out.println(byteBuffer.getInt());
}

输出
在这里插入图片描述

如有错误,请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值