计算机原理:二进制与数据存储
计算机底层只处理二进制。数字、字符、图片、音频和视频最终都会转换为由 0 和 1 组成的数据。
bit、byte 与容量单位

bit(比特)是最小的信息单位,取值只有 0 或 1;8 个 bit 组成 1 个 byte(字节)。Java 中 int 的“4 字节”、long 的“8 字节”都是以 byte 为单位。
| 单位 | 含义 | 常见用途 |
|---|---|---|
bit / b | 一个二进制位 | 网络带宽,如 100 Mbps |
byte / B | 8 bit | 文件、内存、Java 类型大小 |
KB、MB、GB、TB | 十进制单位,每级 1000 倍 | 硬盘标称容量、网络 |
KiB、MiB、GiB、TiB | 二进制单位,每级 1024 倍 | 操作系统、程序运行环境 |
1 B = 8 b
1 KiB = 1024 B
1 MiB = 1024 KiB
1 GiB = 1024 MiB日常交流常把 1 KB 说成 1024 B;严格来说,KB 是 1000 B,KiB 才是 1024 B。磁盘标称容量与系统显示容量不一致,通常就是单位口径不同。
字符、多媒体与文件数据
字符存储的是字符编码对应数字的二进制形式。ASCII 中常见字符的编码如下:
| 字符 | ASCII 数值 | 二进制表示 |
|---|---|---|
A | 65 | 01000001 |
a | 97 | 01100001 |
0 | 48 | 00110000 |
Java 的 char 使用 UTF-16 代码单元,因此字符范围不止 ASCII;A 的编码值恰好与 ASCII 相同。文本文件常用 UTF-8 编码。
文件的本质
文件本质上是一串字节。文本文件、图片、音频和视频的区别,不在于磁盘存储方式,而在于程序按照什么规则解释这些字节。
| 文件类型 | 字节中主要保存的内容 | 常见解析方式 |
|---|---|---|
| 文本文件 | 字符编码后的字节 | 按 UTF-8、GBK 等字符集解码 |
| 图片 | 像素、颜色、尺寸和压缩数据 | PNG、JPEG 等图片解码器 |
| 音频 | 采样数据或压缩后的音频帧 | MP3、AAC、WAV 等音频解码器 |
| 视频 | 视频帧、音频、时间信息和编码数据 | 容器解析后分别解码音视频轨道 |
文件开头通常包含格式标识和元数据,常被称为“文件头”或魔数。例如 PNG 文件以特定字节开头,程序据此判断如何解析。扩展名只是便于用户和系统识别的名称;把 photo.png 改为 photo.jpg 不会把 PNG 转成 JPEG,文件中的字节没有改变。
音频如何转换与播放
现实声音是连续信号,数字音频需要经过采样和量化:在固定时间间隔记录声音强度,再把强度转换为可存储的整数值。WAV 常用于保存接近原始的 PCM 采样数据;MP3、AAC 等编码格式会通过压缩减少体积。
声音信号 → 采样 → 量化 → PCM 数据 → 音频编码/压缩 → 音频文件
音频文件 → 解码 → PCM 数据 → 数模转换 → 扬声器播放
图左是连续的声音波形;图右将波形按固定时间点采样,再把每个采样点量化到有限等级。等级可以用二进制编码,例如 3 位可表示 000 ~ 111 共 8 个等级。连续的编码结果按字节写入文件,便形成 PCM 等数字音频数据。
采样率决定每秒记录多少次,例如 44.1 kHz 表示每秒采样 44100 次;位深影响每次采样可表示的精细程度。采样率、位深和声道数越高,通常音质与文件体积也越高。
视频如何转换与播放
视频可以理解为连续画面加上音频。原始视频每一帧都是大量像素数据,体积非常大,因此通常先使用 H.264、H.265、AV1 等视频编码器压缩;编码器会利用同一帧中的相似区域,以及相邻帧之间的变化来减少重复数据。
摄像头画面 → 视频帧 → 视频编码
麦克风声音 → 音频采样 → 音频编码
视频流 + 音频流 + 时间信息 → MP4 / MKV 等容器文件MP4、MKV 是容器格式,负责组织音视频流、字幕和时间信息;H.264、AAC 等是编码格式,负责压缩和解码具体的音频或视频数据。播放器先解析容器,再解码各轨道,最后按时间戳同步播放。
二进制与十进制转换
进制只改变数值的表示形式。理解二进制与十进制之间的转换,是继续学习八进制、十六进制和 Java 整数字面量的基础。
二进制转十进制
从右向左,每一位乘以对应的 2 的幂,再求和。

0b10110 = 1 × 2⁴ + 0 × 2³ + 1 × 2² + 1 × 2¹ + 0 × 2⁰
= 16 + 4 + 2
= 22public class BinaryValueDemo {
public static void main(String[] args) {
int value = 0b10110;
System.out.println(value); // 22
}
}十进制转二进制
对十进制整数持续除以 2 并记录余数,直到商为 0;将余数从下往上读取。
22 ÷ 2 = 11 ··· 0
11 ÷ 2 = 5 ··· 1
5 ÷ 2 = 2 ··· 1
2 ÷ 2 = 1 ··· 0
1 ÷ 2 = 0 ··· 1
结果:10110八进制与十六进制
为了便于观察和表示二进制,常使用八进制和十六进制。Java 整数最终仍以二进制参与运算,10、0b1010 和 0xA 表示相同的数值。
| 进制 | 基数 | Java 前缀 | 示例 | 十进制值 |
|---|---|---|---|---|
| 二进制 | 2 | 0b 或 0B | 0b1010 | 10 |
| 八进制 | 8 | 0 | 012 | 10 |
| 十进制 | 10 | 无 | 10 | 10 |
| 十六进制 | 16 | 0x 或 0X | 0xA | 10 |

public class RadixLiteralDemo {
public static void main(String[] args) {
int binary = 0b110; // 6
int octal = 0141; // 97
int hexadecimal = 0x61; // 97
int amount = 1_000_000; // 下划线只用于提高可读性
System.out.println(binary); // 6
System.out.println(octal); // 97
System.out.println(hexadecimal); // 97
System.out.println(amount); // 1000000
}
}Java 编译器会先把这些字面量转换为同一个整数值,运行时变量里不会保留“这是八进制还是十六进制”的信息。八进制以单个 0 开头,容易和普通数字混淆;除文件权限等明确场景外,更推荐使用十进制或十六进制。
二进制与八、十六进制
二进制每 3 位对应 1 位八进制,每 4 位对应 1 位十六进制;从右侧开始分组,不足时左侧补 0。
| 二进制 | 八进制 | 十六进制 | 十进制 |
|---|---|---|---|
110 | 6 | 6 | 6 |
1010 | 12 | A | 10 |
11111111 | 377 | FF | 255 |
十六进制中,A ~ F 分别表示十进制的 10 ~ 15。颜色值、字节码和内存地址中经常会看到十六进制。
Java 中的转换
Integer 提供了常用转换方法。字符串转数字时要明确传入原字符串的进制。
public class RadixConvertDemo {
public static void main(String[] args) {
int decimal = Integer.parseInt("1010", 2); // 10
int hexValue = Integer.parseInt("FF", 16); // 255
String binary = Integer.toBinaryString(10); // "1010"
String octal = Integer.toOctalString(255); // "377"
String hex = Integer.toHexString(255); // "ff"
System.out.println(decimal); // 10
System.out.println(hexValue); // 255
System.out.println(binary); // 1010
System.out.println(octal); // 377
System.out.println(hex); // ff
}
}Integer.parseInt(text, radix) 将指定进制的字符串转为十进制整数;toBinaryString、toOctalString、toHexString 则将整数转为对应进制的字符串。
| 场景 | Java | JavaScript / TypeScript |
|---|---|---|
| 二进制字面量 | 0b1010 | 0b1010 |
| 八进制字面量 | 012,不建议日常使用 | 0o12 |
| 十六进制字面量 | 0xFF | 0xFF |
| 字符串转十进制 | Integer.parseInt("1010", 2) | parseInt("1010", 2) |
| 转二进制字符串 | Integer.toBinaryString(10) | (10).toString(2) |
小结
- 计算机底层以二进制存储数据,
bit表示一个0或1,1 B = 8 b;容量单位要区分十进制的KB与二进制的KiB。 - 字符、图片、音频和视频最终都是二进制数据。字符需要依赖编码规则解释,Java
char使用 UTF-16 代码单元,文本文件常用 UTF-8;文件扩展名不会改变文件真实格式。 - 数字音频通过采样、量化、编码生成;视频由视频帧、音频和时间信息组成,通常先编码压缩,再封装到 MP4、MKV 等容器中。
- 二、八、十、十六进制是同一个数值的不同表示形式;Java 中分别使用
0b、0、无前缀和0x书写整数字面量。 - 二进制转十进制使用按位权求和;十进制转二进制使用除二取余;二进制与八、十六进制之间可分别按 3 位和 4 位分组转换。
- 代码中可使用
Integer.parseInt(text, radix)解析指定进制的字符串,使用toBinaryString、toOctalString、toHexString输出对应进制的字符串。
