1. 使用原生 Java
✅ 最推荐的方式:直接使用 InputStreamReader
,简单粗暴,无需额外依赖。
InputStream
是字节流,而 Reader
是字符流,转换时必须指定字符编码(charset),否则可能踩坑乱码问题。如果不指定,会使用平台默认编码(如 Windows 的 GBK),跨平台时容易出问题。
@Test
public void givenUsingPlainJava_whenConvertingInputStreamIntoReader_thenCorrect()
throws IOException {
InputStream initialStream = new ByteArrayInputStream("With Java".getBytes(StandardCharsets.UTF_8));
Reader targetReader = new InputStreamReader(initialStream, StandardCharsets.UTF_8);
// 使用后记得关闭
targetReader.close();
}
📌 关键点:
- ✅ 推荐显式指定
UTF-8
- ✅
InputStreamReader
是Reader
的子类,天然桥接字节流与字符流 - ❌ 避免不指定编码的构造函数(已过时)
2. 使用 Guava
Guava 的方式略显绕路:先转成 byte[]
,再转成 String
,最后包装成 Reader
。虽然能用,但多了一次内存拷贝,性能不如原生 Java。
@Test
public void givenUsingGuava_whenConvertingInputStreamIntoReader_thenCorrect()
throws IOException {
InputStream initialStream = ByteSource.wrap("With Guava".getBytes(StandardCharsets.UTF_8)).openStream();
byte[] buffer = ByteStreams.toByteArray(initialStream);
Reader targetReader = CharSource.wrap(new String(buffer, StandardCharsets.UTF_8)).openStream();
targetReader.close();
}
📌 分析:
- ⚠️ 多次中间转换,浪费内存和 CPU
- ✅ 代码可读性尚可,适合 Guava 重度使用者
- ❌ 不推荐用于高频调用场景
小贴士:如果你项目已经在用 Guava,且只是偶尔转换,那也无所谓。但性能敏感场景请绕行。
3. 使用 Apache Commons IO
Commons IO 的做法和 Guava 类似,也是通过 byte[] → String → Reader
的链路。它提供了 CharSequenceReader
来包装字符串。
@Test
public void givenUsingCommonsIO_whenConvertingInputStreamIntoReader_thenCorrect()
throws IOException {
InputStream initialStream = IOUtils.toInputStream("With Commons IO", StandardCharsets.UTF_8);
byte[] buffer = IOUtils.toByteArray(initialStream);
Reader targetReader = new CharSequenceReader(new String(buffer, StandardCharsets.UTF_8));
targetReader.close();
}
📌 注意点:
- ✅
IOUtils.toInputStream(String, Charset)
很方便 - ⚠️
toByteArray()
会一次性加载整个流到内存,大文件有 OOM 风险 - ❌ 同样存在多余对象创建,效率低于原生方案
总结对比
方式 | 是否需要依赖 | 推荐程度 | 适用场景 |
---|---|---|---|
原生 Java | ❌ | ✅✅✅ | 所有场景,首选方案 |
Guava | ✅ | ✅ | 已引入 Guava 的项目 |
Commons IO | ✅ | ✅ | 已引入 Commons IO 的旧项目 |
✅ 最终建议:
优先使用
InputStreamReader(inputStream, StandardCharsets.UTF_8)
,简单、高效、安全。
其他方式仅作为已有技术栈下的兼容选择,不要为了用而用。