读取InputStream到字节数组后转换为String无输出的问题排查
问题分析与解决:InputStream读取文件无法得到有效String输出
问题描述
运行代码后能获取到正常日志(len有有效值43681,对应42.7KB的目标文件),但最终无法得到有效的String输出,想排查转换过程中的错误:
原代码
FileServices fs = new FileServices(""); InputStream in = fs.getInputStreamFromVault(location); int len; String strFileContents = ""; logger.info(logPrefix + "file1 "); BufferedInputStream inBuff = new BufferedInputStream(in); logger.info(logPrefix + "file2 "); byte[] buf = new byte[564000]; logger.info(logPrefix + "file3 "); int bytesRead = 0; while ((len = inBuff.read(buf)) > 0) { logger.info(logPrefix + "file4 "); logger.info("len " + len); strFileContents += new String(buf, 0, bytesRead); logger.info("bytesRead " + bytesRead); //String string = new String(buf, "UTF-8"); //stream.write(buf, 0, len); logger.info("strFileContents " + strFileContents); }
日志输出
INFO : [prefix] file1 INFO : [prefix] file2 INFO : [prefix] file3 INFO : [prefix] file4 INFO : len 43681 INFO : bytesRead 0 INFO : strFileContents
问题排查与解决
我帮你梳理下代码里的问题,核心错误和优化点如下:
1. 核心错误:拼接字符串时用错了长度变量
你定义了bytesRead但全程没有更新它的数值,初始值是0,循环里拼接字符串时用的是new String(buf, 0, bytesRead)——这意味着每次都从byte数组里截取0个字节,自然拼出来的是空字符串!
而日志里显示的len才是每次实际读取到的有效字节数(43681,正好是你的文件大小),所以必须用len来作为截取byte数组的长度参数。
2. 性能优化:避免直接拼接String
直接用strFileContents += ...拼接字符串,每次都会创建新的String对象,对于大文件来说性能损耗很大,推荐用StringBuilder来做字符串拼接,效率会高很多。
3. 编码显式指定(避免乱码)
你注释掉了指定UTF-8编码的代码,建议显式指定编码格式,避免依赖系统默认编码导致不同环境下出现乱码问题。
修正后的代码示例
import java.nio.charset.StandardCharsets; // ... 其他代码 FileServices fs = new FileServices(""); InputStream in = fs.getInputStreamFromVault(location); int len; // 改用StringBuilder高效拼接 StringBuilder strFileContents = new StringBuilder(); logger.info(logPrefix + "file1 "); BufferedInputStream inBuff = new BufferedInputStream(in); logger.info(logPrefix + "file2 "); byte[] buf = new byte[564000]; logger.info(logPrefix + "file3 "); while ((len = inBuff.read(buf)) > 0) { logger.info(logPrefix + "file4 "); logger.info("len " + len); // 用len作为有效字节长度,显式指定UTF-8编码 strFileContents.append(new String(buf, 0, len, StandardCharsets.UTF_8)); logger.info("strFileContents length: " + strFileContents.length()); } // 最后转换为String String result = strFileContents.toString();
修正后,strFileContents就能正确累积文件的内容了,而且性能和编码稳定性都得到了提升。
内容的提问来源于stack exchange,提问作者user2568374
相关产品推荐
相关产品推荐

