浅谈 &0xFF操作

浅谈 &0xFF操作在java.io.FilterOutputStream.DataOutputStream:与机器无关地写入各种类型的数据以及String对象的二进制形式,从高位开始写。这样一来,任何机器上任何DataInputStream都能够读取它们。所有方法都以“write”开头,例如writeByte(),writeFloat()等。java.io.FilterOutputStream.PrintSt

大家好,又见面了,我是你们的朋友全栈君。

本文章为博主原创文章,未经授权,不得转载。

在java.io.FilterOutputStream.DataOutputStream:与机器无关地写入各种类型的数据以及String对象的二进制形式,从高位开始写。这样一来,任何机器上任何DataInputStream都能够读取它们。所有方法都以“write”开头,例如writeByte(),writeFloat()等。 

java.io.FilterOutputStream.PrintStream最初的目的是为了以可视化格式打印所有的基本数据类型以及String对象。这和DataOutputStream不同,它目的是将数据元素置入“流”中,使DataInputStream能够可移植地重构它们。

对于如何把一串字符串写成二进制,我一直迷惑不解,直到我看到下面的信息:

字符串的本质是char的序列,也就是char [ ]。因此,遍历写入每一个char,就完成了写一个字符串的功能!

那么问题又来了,如何把char写成二进制呢?

英语字母有ASCII码,可以把每个字符转换成对应的数字,那么汉字呢,日语呢,韩语呢,泰国语呢????????????????????????????????????????????????????

把心放肚子里吧,这个问题前人早就已经解决了。世界上的绝大部分字符都有一张类似于ASCII码表的字符和编码间的映射,那就是Unicode码表。看:

Unicode 字符编码标准是固定长度的字符编码方案,它包含了世界上几乎所有现用语言的字符。有关 Unicode 的信息可在最新版本的 The Unicode Standard 一书中找到,并可从 Unicode 协会 Web 站点(www.unicode.org)中找到。 Unicode 根据要编码的数据类型使用两种编码格式:8 位和 16 位。缺省编码格式是 16 位,即每个字符是 16 位(两个字节)宽,并且通常显示为 U+hhhh,其中 hhhh 是字符的十六进制代码点。虽然生成的 65000 多个代码元素足以用于 编码世界上主要语言的大多数字符,但 Unicode 标准还提供了一种扩展机制,允许编码一百多万个字符。扩展机制使用一对高位和低位代用字符来对扩展字符或补充字符进行编码。第一个(或高位)代用字符具有 U+D800 和 U+DBFF 之间的代码值,而第二个(或低位)代用字符具有 U+DC00 和 U+DFFF 之间的代码值。

unicode码真的可以用2个字节表示世界上的绝大部分字符。

至此,当看到一个char时,我仿佛看到了它背后隐隐欲现的0-65535间的数字,当看到一个String时,我仿佛看到了一串数字!

所以,DataOutputStream.writeChars(str)的源码也就明晰了

public final void writeChars(String s) throws IOException {
        int len = s.length();
      
        for (int i = 0 ; i < len ; i++) {
            int v = s.charAt(i);
            out.write((v >>> 8) & 0xFF); 
            out.write((v >>> 0) & 0xFF); 
        }
        incCount(len * 2);
    }

所以除了要遍历一遍string之外,其他的操作Yu DataOutputStream.writeShort(v)的源码没什么区别

public final void writeShort(int v) throws IOException {
        out.write((v >>> 8) & 0xFF);
        out.write((v >>> 0) & 0xFF);
        incCount(2);
    }

至此,就把一串字符串写成二进制了。

但是,你有没有一个疑问????????为什么(v >>> 8) & 0xFF ??为什么(v >>> 0) & 0xFF????不知道你有没有,反正我有。

具体疑问:1 为什么要用无符号的右移? 2 &0xFF不会使数的大小改变,为什么还要 &0xFF?

先科普一下:

0(零)xFF是16进制的255,也就是二进制的 1111,1111

& AND 按位与操作,同时为1时才是1,否则为0.

————位移运算计算机中存的都是数的补码,所以位移运算都是对补码而言的————

<< 左移 右补0

>> 有符号右移 左补符号位,即:如果符号位是1 就左补1,如果符号位是0 就左补0

>>>无符号右移 ,顾名思义,统一左补0

————————————————————————————————————————

要想知道为什么?我们应该想想,我们的目的是干什么的?开始已经讲了:先取高8位写入,再写入低8位.。

0000,0000,0000,0011     3的二进制原码,假设要写入的short字符对应的unicode码是3。

0000,0000,0000,0000      这是”>>>8″的结果                        

                  1111,1111       然后再 &0XFF                                                                         

                 0000,0000       最终结果                                                                                    

   这就得到了 3的原码0000,0000,0000,0011 的高8位。

    0000,0000,0000,0011        >>>0还是源码本身不变

                       1111,1111        &0XFF                                                                       

                      0000,0011        最终结果
这就得到了 3的原码0000,0000,0000,0011 的低8位。

其实,用有符号的右移>>也一样得到高/低8位,因为右移操作不改变数本身,返回一个新值,就像String。所以 “&0xFF” 就像计算机中的一把剪刀,当‘&’操作符两边数的bit位数相同时不改变数的大小,只是专门截出一个字节的长度。同理,&0x0F呢?得到4bits

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/150768.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月19日 下午8:16
下一篇 2022年6月19日 下午8:16


相关推荐

  • 软件工程职业规划

    软件工程职业规划一 语言的选择 Python JAVA C PHP C VB 10 多种热门的开发语言 哪一种最有发展潜力呢 其实开发语言只不过是一个工具 与其分散进攻 不如全力一击 无论是哪一种开发语言 只要您全力地去学习 到有了一定的熟悉程度的时候 要学习另一种的语言也是轻而易举的事情 开发语言主要分为三大类 1 网络开发现在网络已经成为世界通讯的一座桥梁 好像 Javascript PHP Ruby 这几类开发语言大部分是用作网络开发方面 2 企业软件开发 JAVA C VB 这几类开发语言都实现了面向对

    2026年3月17日
    1
  • 云计算平台简介(App Engine)

    云计算平台简介(App Engine)1 nbsp nbsp 简介 AppEngine 应用程序引擎 是托管网络应用程序的云计算平台 nbsp 1 1 nbsp 什么是云 nbsp 云计算通常简称为 云 是一种通过 Internet 按需交付计算资源 从应用到数据中心都属于计算资源 和按使用付费的基础架构 nbsp 富有弹性的资源 能快速轻松地扩大或缩小规模 以满足您的需求按使用付费 计量服务的使用情况 只需为所用的服务付费

    2026年3月26日
    1
  • 计算机网络vlan的作用,计算机网络之九:VLAN

    计算机网络vlan的作用,计算机网络之九:VLAN一:什么是VLAN广播在网络中起着非常重要的作用,如发现新设备,调整网络路径,IP地址租赁等,许多网络协议都要用到广播。然而,随着网络内计算机数量的增多,广播包的数量也会急剧增加,当广播包的数量占到通讯总量的30%时,网络的传输效率将会明显下降。所以当局域网内的计算机达到一定数量后,通常采用划分VLAN(虚拟局域网)的方式将网络分隔开来。将一个大的广播域划分为若干个小的广播域,以减小广播可能造成的…

    2022年8月10日
    7
  • C++使用CreateMutex

    C++使用CreateMutex一 定义 HANDLECreate LPSECURITY ATTRIBUTESlp 指向安全属性的指针 BOOLbInitial 初始化互斥对象的所有者 LPCTSTRlpNam 指向互斥对象名的指针 第一个参数是一个指向 SECURITY ATTRIBUTES 结构体的指针 一般的情况下 可以是 nullptr 第二个参数类型为 BOOL 表示互斥锁创建出来后是否被当前线程持有 第三个参数类型为字符串 con

    2025年9月14日
    6
  • 数据仓库(四)之ETL开发

    数据仓库(四)之ETL开发 概述 ETL是数据仓库的后台,主要包含抽取、清洗、规范化、提交四个步骤,传统数据仓库一般分为四层模型。               分层的作用                                      STG层  在维度建模阶段已经确定了源系统,而且对源系统进行了…

    2022年6月13日
    37
  • 网站的栏目页是什么_栏目页

    网站的栏目页是什么_栏目页功能说明栏目子分类列表,栏目导航适用范围首页模板,列表模板,内容模板基本语法[NT:unLoop,NT:SiteID=0,NT:LabelType=ClassNavi,NT:ClassID=ClassID,NT:HrefCSS=HrefCSS,NT:NaviChar=NaviChar,NT:isDiv=false,NT:Cols=1][/NT:unLoop…

    2026年4月17日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号