1 计算机基础
1.1 二进制
二进制数据是用0和1两个数码来表示的数:它的基数为2,进位规则是"逢二进一",借位规则是"借一当二"。
当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的。
1.1.1 bit Byte KB MB关系
- 1 bit
计算机中的二进制位(bit)是长度单位,是一个非常微小的开关,用"开"来表示1,"关"来表示0。
因为计算机通信和存储的时候都是以010101这样的二进制数据为基础的,这儿的一个0和1占的地方就叫bit(位),即一个二进制位。 - 2 Byte
字(Byte)节也是长度单位。
Byte是一个字节保存的,有8个bit位,即8个0或1,8位的第一个位是符号位。
00000001[二进制]=1[十进制]
10000000[二进制]=-1[十进制]
二进制区间[127~-128]:
正: 01111111[二进制]=127 [十进制]
正: 11111111[二进制]=-128 [十进制]
负数最大为1111 1111,也就是数字-128
- 3 单位关系
单位 | 关系 |
---|---|
1Byte | 8bit |
1KB | 1024B |
1MB | 1024KB |
1GB | 1024MB |
1.2 八进制
Octal,缩写OCT或O,一种以8为基数的计数法,采用0,1,2,3,4,5,6,7八个数字,逢八进1。
一些编程语言中常常以数字0开始表明该数字是八进制,八进制的数和二进制数可以按位对应(八进制一位对应二进制三位),因此常应用在计算机语言中。
1.3 十六进制
十六进制(英文名称:Hexadecimal),是计算机中数据的一种表示方法。同我们日常生活中的表示法不一样。
它由0-9,A-F组成,字母不区分大小写,与10进制的对应关系是:0-9对应0-9;A-F对应10-15;N进制的数可以用0~(N-1)的数表示,超过9的用字母A-F。
2 Java中的各进制、字节流和字符流
2.1 代码中使用
- 1 代码表示
以0b
开始的数据表示二进制
以0
开始的数据表示八进制
以0x
开始的数据表示十六进制
- 2 打印
打印二进制
:Integer.toBinaryString(int i)
打印八进制
:Integer.toOctalString(int i)
打印十六进制
:Integer.toHexString(int i)
2.2 Java的基本数据类型长度
数据类型 | 占用字节 |
---|---|
char | 2个Byte(2*8bit) |
short | 2个Byte(2*8bit) |
int | 4个Byte(4*8bit) |
long | 8个Byte(8*8bit) |
float | 4个Byte(4*8bit) |
double | 8个Byte(8*8bit) |
2.3 字节流和字符流
程序中所有的数据都是以流的方式进行传输或保存的,流中保存的实际上是字节文件,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。
2.3.1 字节流与字符流
在java.io
包中操作文件内容的主要有两大类:字节流
、字符流
,两类都分为输入
和输出
操作。
在字节流中输出数据主要是使用OutputStream
完成,输入使的是InputStream
,在字符流中输出主要是使用Writer
类完成,输入流主要使用Reader
类完成(这四个都是抽象类
)。
2.3.2 Java.io包
Java.io包其中包括:InputStream
,OutputStream
,Reader
,Writer
;
-
InputStream
、OutputStream
:为字节流,主要用来处理字节或二进制对象。
如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点,所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。
在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列,字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; -
Reader
、Writer
:为字符流(一个字符占两个字节),主要用来处理字符或字符串。
字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。
所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好。
字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以字节流是最基本的,所有的InputStrem和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的。
实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化 这两个之间通过 InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联 在实际开发中出现的汉字问题实际上都是在字符流和字节流之间转化不统一而造成的 。
2.3.3 字节流与字符流的区别
- 1 字节流和字符流使用是非常相似的,那么除了操作代码的不同之外,还有哪些不同呢?
字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的。
字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容
- 2 那开发中究竟用字节流好还是用字符流好呢?
在所有的硬盘上保存文件或进行传输的时候都是以字节的方法进行的,包括图片也是按字节完成,而字符是只有在内存中才会形成的,所以使用字节的操作是最多的。
如果要java程序实现一个拷贝功能,应该选用字节流进行操作(可能拷贝的是图片),并且采用边读边写的方式(节省内存)。
3 原码、反码、补码
我们来谈谈另一个话题:原码、反码、补码。
计算机中,所有数据最终都是使用二进制数表达。
负数如何用二进制表达呢
在计算机中,负数以其正值的补码形式表达。
3.1 原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。
假设有一个int 类型的数,值为5,那么,我们知道它在计算机中表示为:5
其原码如下:
00000000|00000000|00000000|00000101
3.2 反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。
取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
其反码如下:
11111111|11111111|11111111|11111010
3.3 补码:反码加1称为补码。
其补码如下:
11111111|11111111|11111111|11111010 + 1 = 11111111|11111111|11111111|11111011
再举一例:
-1在计算机中如何表示。
1、先取1的原码:
00000000|00000000|00000000|00000001
2、得反码:
11111111|11111111|11111111|11111110
3、得补码:
11111111|11111111|11111111|11111111
可见-1在计算机里用二进制表达就是全1,16进制为:0xFFFFFFFF。