- 转换为二进制字符串:将每个字节转换为它的8位二进制表示(
1变成"00000001"),这是最常见的需求。 - 转换为二进制数据流:将字节数组直接写入输出流,如
OutputStream,这在处理文件、网络传输等 I/O 操作时非常常用。 - 转换为十六进制字符串:虽然不是二进制,但这是表示字节数据的另一种非常流行且紧凑的方式,因为它每个字符代表4位二进制。
下面我将详细介绍这几种方法,并提供完整的代码示例。

转换为二进制字符串
这是最直接的理解“转换”的方式,我们将遍历 byte 数组中的每一个字节,并将其格式化为一个8位的二进制字符串。
核心思路
- 遍历
byte数组。 - 对于每个
byte,使用Integer.toBinaryString()方法将其转换为二进制字符串。 Integer.toBinaryString()会返回一个无前导零的字符串(1会变成"1"),所以我们需要手动补足前导零,确保每个字节都是8位。- 将所有8位的二进制字符串拼接起来。
代码示例
import java.nio.charset.StandardCharsets;
public class ByteArrayToBinary {
public static void main(String[] args) {
// 示例字节数组: 'A' -> 65, 'B' -> 66, 'C' -> 67
// 65 in binary is 01000001
// 66 in binary is 01000010
// 67 in binary is 01000011
byte[] bytes = {'A', 'B', 'C'};
// 方法1: 使用 String.format 进行格式化
String binaryString1 = bytesToBinaryStringUsingFormat(bytes);
System.out.println("方法1 (String.format): " + binaryString1);
// 方法2: 使用 Integer.toBinaryString 并手动补零
String binaryString2 = bytesToBinaryStringManualPadding(bytes);
System.out.println("方法2 (手动补零): " + binaryString2);
}
/**
* 使用 String.format 将 byte 数组转换为二进制字符串
* @param bytes 输入的字节数组
* @return 每个字节都转换为8位二进制并拼接后的字符串
*/
public static String bytesToBinaryStringUsingFormat(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
// %8s 表示一个至少8个字符宽的字符串,右对齐
// 0 表示用 '0' 填充空位
// String.format 会将 byte 自动转为 int,然后格式化为二进制
sb.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0'));
}
return sb.toString();
}
/**
* 使用 Integer.toBinaryString 并手动补零将 byte 数组转换为二进制字符串
* @param bytes 输入的字节数组
* @return 每个字节都转换为8位二进制并拼接后的字符串
*/
public static String bytesToBinaryStringManualPadding(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
// 1. 将 byte 转换为无符号的 int 值,避免负数问题
// b & 0xFF 是一个常用的技巧,可以确保 byte 被当作 0-255 的正数处理
int val = b & 0xFF;
// 2. 转换为二进制字符串
String s = Integer.toBinaryString(val);
// 3. 手动补前导零
// 因为 toBinaryString 不会生成前导零,所以我们需要检查长度
if (s.length() < 8) {
sb.append("00000000".substring(s.length()));
}
sb.append(s);
}
return sb.toString();
}
}
输出结果
方法1 (String.format): 010000010100001001000011
方法2 (手动补零): 010000010100001001000011
关键点解释
b & 0xFF:这是最重要的一步,Java 中的byte是有符号的(范围是 -128 到 127),当你将一个负数byte(-1)直接传递给Integer.toBinaryString()时,它会得到一个32位的二进制补码表示(11111111111111111111111111111111),这显然不是我们想要的。b & 0xFF通过位运算,将byte提升为int,同时只保留低8位,得到一个 0-255 之间的无符号整数,这确保了每个字节都被正确地转换为8位二进制。String.format("%8s", ...).replace(' ', '0'):这是一种非常简洁的补零方式。%8s会将字符串格式化为8个字符宽度,不足的部分用空格填充,然后我们再用replace将这些空格替换为0。
转换为二进制数据流
如果你不是想得到一个字符串,而是想把二进制数据写入文件或通过网络发送,那么你应该直接使用 java.io 包中的流。
核心思路
使用 FileOutputStream 将 byte 数组直接写入文件,文件本身就是二进制数据的存储形式。
代码示例
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class ByteArrayToBinaryStream {
public static void main(String[] args) {
// 准备要写入的字节数据
String data = "Hello, Java!";
byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
// 定义输出文件路径
String filePath = "output.bin";
try (FileOutputStream fos = new FileOutputStream(filePath)) {
// 直接将字节数组写入文件输出流
fos.write(bytes);
System.out.println("字节数组已成功写入文件: " + filePath);
} catch (IOException e) {
System.err.println("写入文件时发生错误: " + e.getMessage());
e.printStackTrace();
}
}
}
运行此代码后,会在项目根目录下创建一个名为 output.bin 的文件,你可以使用任何十六进制编辑器(如 HxD, WinHex, VS Code 的 Hex Editor 插件)打开它,就能看到原始的二进制数据。

转换为十六进制字符串(常用替代方案)
要求是二进制,但在实际开发中,将字节数组转换为十六进制字符串更为常见,因为:
- 更紧凑:每两个十六进制字符代表一个字节,比8位二进制字符串短得多。
- 可读性更好:
"A1B2"比"1010000110110010"更容易阅读和调试。 - 不易出错:避免了一长串
0和1的视觉混淆。
核心思路
遍历每个字节,将其转换为两个十六进制字符(0-9, A-F)。
代码示例
import java.nio.charset.StandardCharsets;
public class ByteArrayToHex {
public static void main(String[] args) {
String data = "ABC";
byte[] bytes = data.getBytes(StandardCharsets.UTF_8); // 结果是 {65, 66, 67}
// 方法1: 使用 String.format (类似二进制的方法)
String hexString1 = bytesToHexStringUsingFormat(bytes);
System.out.println("方法1 (String.format): " + hexString1);
// 方法2: 使用 Integer.toHexString 并手动补零
String hexString2 = bytesToHexStringManualPadding(bytes);
System.out.println("方法2 (手动补零): " + hexString2);
// 方法3: 使用第三方库 (如 Apache Commons Codec) - 推荐在生产环境使用
// String hexString3 = Hex.encodeHexString(bytes);
// System.out.println("方法3 (Apache Commons): " + hexString3);
}
public static String bytesToHexStringUsingFormat(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
// %02x 表示将整数格式化为2位的小写十六进制数,不足用0填充
sb.append(String.format("%02x", b & 0xFF));
}
return sb.toString();
}
public static String bytesToHexStringManualPadding(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
int val = b & 0xFF;
// Integer.toHexString 不会生成前导零,需要手动处理
if (val < 16) {
sb.append("0");
}
sb.append(Integer.toHexString(val));
}
return sb.toString();
}
}
输出结果
方法1 (String.format): 414243
方法2 (手动补零): 414243
| 需求场景 | 推荐方法 | 优点 | 缺点 |
|---|---|---|---|
| 查看/调试每个字节的二进制位 | 转为二进制字符串 | 直观,完全符合字面意思 | 字符串冗长,不适合大量数据 |
| 将数据持久化到文件或网络传输 | 写入二进制流 | 高效,直接操作原始数据 | 不能直接用于日志或控制台显示 |
| 紧凑地表示或传输字节数据 | 转为十六进制字符串 | 紧凑、可读、通用 | 不是原始的二进制位表示 |
对于大多数开发需求,方法一 和 方法三 是最常用的,如果你只是想看看数据长什么样,用方法一;如果你需要传输或存储一个紧凑的文本表示,用方法三。

