StandardCharsets 是字符编码规范提供者,用于 NIO 通道中字节与字符串的转换;必须在文本读写时通过 encode/decode 方法指定编码,如 UTF_8.encode(str) 和 decode(buffer),确保类型安全、零开销且避免乱码。
`StandardCharsets` 本身不直接参与 NIO 通道(Channel)的数据传输过程,它不“在通道中”,而是作为**字符编码规范的提供者**,在通道与字符串之间做桥梁——尤其当数据需要以文本形式读写时,必须通过 `StandardCharsets` 指定如何把字节(`byte[]` 或 `ByteBuffer`)和字符(`String`、`CharBuffer`)相互转换。
下面从实际使用场景出发,讲清楚它怎么用、在哪用、为什么不能少:
什么时候必须用 StandardCharsets?
当你用 NIO 通道处理文本内容,并且涉及
字符串 ↔ 字节数组 ↔ ByteBuffer
的转换时。例如:
把一个
写入
或
,得先转成字节 —— 就要用
得到
从通道读出字节到
后,想还原成可读字符串 —— 就得用
用
或
这类 NIO.2 工具方法时,
参数通常传
为什么不用 new String(bytes, "UTF-8")?
虽然传统方式能用,但存在两个隐患:
字符串字面量不可靠
:比如写
拼错成
,运行时报
;而
是编译期常量,IDE 可自动补全、类型安全
避免重复创建 Charset 实例
:每次调用
都会查表、加锁、可能触发 GC;
中的字段是静态 final 单例,零开销复用
典型配合 Channel 的代码片段
比如用
写入 UTF-8 文本:
再比如从通道读取后解码:
注意 UTF-16 和大小端问题
是平台相关编码,实际使用较少;更推荐明确指定:
(大端)或
(小端)
尤其在跨系统通信(如 Java ↔ C/C++ 程序)时,字节序必须一致,否则解码乱码
一般 Web/文件交互首选
,兼容性最好,无字节序歧义
不复杂但容易忽略。
StringFileChannelSocketChannelStandardCharsets.UTF_8.encode(str)ByteBufferByteBufferStandardCharsets.UTF_8.decode(buffer).toString()Files.readString(path, charset)Files.write(path, bytes, charset)charsetStandardCharsets.UTF_8"UTF-8""UTf-8"UnsupportedCharsetExceptionStandardCharsets.UTF_8Charset.forName("UTF-8")StandardCharsetsFileChannel
String content = "你好,世界!";
ByteBuffer buffer = StandardCharsets.UTF_8.encode(content); // → 直接得到含 UTF-8 字节的只读 ByteBuffer
try (FileChannel channel = FileChannel.open(Paths.get("out.txt"),
StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
channel.write(buffer); // 写入字节流
}
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = channel.read(buffer);
buffer.flip();
String text = StandardCharsets.UTF_8.decode(buffer).toString(); // 安全还原为字符串
StandardCharsets.UTF_16StandardCharsets.UTF_16BEStandardCharsets.UTF_16LEUTF_8