代码分享,Inputstream转换String
在本教程中,我们将讲讲如何将一个 InputStream 转换为一个字符串。
我们将从使用普通的 Java 开始,包括 Java 8+ 的解决方案,然后也会研究使用 Guava 和 Apache Commons IO 库。 用 Java 进行转换 - StringBuilder
让我们看看一个简单的、低级别的方法,使用普通的 Java,一个 InputStream 和一个简单的 StringBuilder。 @Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); StringBuilder textBuilder = new StringBuilder(); try (Reader reader = new BufferedReader(new InputStreamReader (inputStream, Charset.forName(StandardCharsets.UTF_8.name())))) { int c = 0; while ((c = reader.read()) != -1) { textBuilder.append((char) c); } } assertEquals(textBuilder.toString(), originalString); } 用 Java 8 进行转换 -- BufferedReader
Java 8 给 BufferedReader 带来了一个新的 lines() 方法。让我们看看如何利用它将一个 InputStream 转换为一个字符串。 @Test public void convertingAnInputStreamToAString() { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = new BufferedReader( new InputStreamReader(inputStream, StandardCharsets.UTF_8)) .lines() .collect(Collectors.joining(" ")); assertThat(text, equalTo(originalString)); }
值得一提的是, lines() 使用的是 readLine() 方法。readLine() 假定一行是由换行(" ") 、回车("r") 或回车后立即换行中的任何一种结束符。换句话说,它支持所有常见的行结束方式。
另一方面,当我们使用 Collectors.join() 时,我们需要明确决定我们要为创建的 String 使用哪种类型的结束符。
我们也可以使用 Collectors.join(System.lineSeparator()) ,在这种情况下,输出结果取决于系统设置。 用 Java 9+ 进行转换 - InputStream.readAllBytes()
如果我们在 Java 9 或以上版本,我们可以利用一个新的 readAllBytes 方法添加到 InputStream 中。 @Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); assertThat(text, equalTo(originalString)); }
我们需要注意的是,这段简单的代码是为那些方便将所有字节读入字节数组的简单情况准备的。我们不应该用它来读取有大量数据的输入流。 用 Java Scanner 进行转换
接下来,让我们看看一个使用标准文本扫描器的普通Java例子。 @Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = null; try (Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name())) { text = scanner.useDelimiter("A").next(); } assertThat(text, equalTo(originalString)); }
请注意,InputStream 将被关闭的 Scanner 关闭。
同样值得澄清的是 useDelimiter("A") 的作用。这里我们传递了"A" ,它是一个边界标记重码,表示输入的开始。本质上,这意味着 next() 调用读取了整个输入流。 使用 ByteArrayOutputStream 进行转换
最后,让我们看看另一个普通的Java例子,这次是使用 ByteArrayOutputStream 类。 @Test public void convertingAnInputStreamToString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[1024]; while ((nRead = inputStream.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); } buffer.flush(); byte[] byteArray = buffer.toByteArray(); String text = new String(byteArray, StandardCharsets.UTF_8); assertThat(text, equalTo(originalString)); }
在这个例子中,InputStream 通过读写字节块被转换为 ByteArrayOutputStream。然后 OutputStream 被转换为一个字节数组,用来创建一个字符串。 用java.nio进行转换
另一个解决方案是将 InputStream 的内容复制到一个文件中,然后将其转换为一个字符串。 @Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); Path tempFile = Files.createTempDirectory("").resolve(UUID.randomUUID().toString() + ".tmp"); Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING); String result = new String(Files.readAllBytes(tempFile)); assertThat(result, equalTo(originalString)); }
这里我们使用 java.nio.file.Files 类来创建一个临时文件,同时将 InputStream 的内容复制到文件中。然后用同一个类用 readAllBytes() 方法将文件内容转换为一个字符串。 用Guava进行转换
让我们从一个利用 ByteSource 功能的 Guava 例子开始。 @Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); ByteSource byteSource = new ByteSource() { @Override public InputStream openStream() throws IOException { return inputStream; } }; String text = byteSource.asCharSource(Charsets.UTF_8).read(); assertThat(text, equalTo(originalString)); }
让我们来看看这些步骤 首先,我们把我们的 InputStream 包装成一个 ByteSource. 其次,我们把 ByteSource 看作是一个具有 UTF8 字符集的 CharSource。 最后,我们使用 CharSource 将其作为一个字符串来读取。
一个更简单的转换方法是使用 Guava,但需要明确地关闭流, 我们可以简单地使用 try-with-resources 语法来处理这个问题。 @Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = null; try (Reader reader = new InputStreamReader(inputStream)) { text = CharStreams.toString(reader); } assertThat(text, equalTo(originalString)); } 用 Apache Commons IO 进行转换
现在让我们来看看如何用 Commons IO 库来做这个。
一个重要的注意事项是,与 Guava 不同的是,这些例子都不会关闭 InputStream。 @Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name()); assertThat(text, equalTo(originalString)); }
我们也可以用一个StringWriter来做转换。 @Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); StringWriter writer = new StringWriter(); String encoding = StandardCharsets.UTF_8.name(); IOUtils.copy(inputStream, writer, encoding); assertThat(writer.toString(), equalTo(originalString)); } 总结
在这篇文章中,我们学习了如何将一个 InputStream 转换为一个字符串。我们从使用普通 Java 开始,然后探索了如何使用 Guava 和 Apache Commons IO 库。
来源 | 公众号Java技术指北 (ID:javanorth)
小米11高端系列手机全球销量突破300万台IT之家5月21日消息今日小米公司宣布,小米1111Pro11Ultra三款高端手机全球销量突破300万台。此外,该系列手机在国内是40006000元价位段是销量最多的安卓手机。官
为什么苹果手机的电池不耐用?苹果手机的电池一直是苹果手机最大的软肋,不少用户表示连新手机不怎么玩游戏都起码要一天一冲。那么苹果手机的电池为什么这么不耐用呢?归根结底是因为苹果手机的电池容量太小。最新的iPho
直播又出假货事件?薇娅被质疑卖山寨商品,还甩锅电商平台小二文AI财经社张可心编辑杨洁直播行业又有头部主播又被卷入了假货风波,这次是薇娅。5月14日,微博注册用户Abestyle公开质疑当晚薇娅直播间售卖的SupremexGUZI联名挂脖小
三大机构封杀虚拟货币,基本上盖棺定论了昨儿大夜里突然平地惊雷,中国人民银行联合中国互联网金融协会中国银行业协会中国支付清算协会发布重要内容,直接对比特币等虚拟币开启封杀模式。在之前的分享中,我们也多次探讨过比特币,我个
炒币惨痛经历一觉醒来资产清零,马斯克真不是个好玩意昨天是个噩梦般的日子,比特币跌了,以太坊跌了,被马斯克力挺的狗狗币也大幅跳水,随着而落的还有我们这些炒币人的心,已经跌得粉碎了。我其实损失得不多,早就把本金提出来了。但是看到各种群
iPhone12现在推荐入手吗简单点现在入手不如等6。18入手!用五年其实和iPhone12关系不大为啥这么说呢?咱们把入手时间和使用年限这两个问题展开讲讲吧一iPhone12的日常价位iPhone12(128
iQOONeo5活力版预热3。5mm耳机孔,环绕式立体双扬IT之家5月21日消息iQOO手机官方今日为iQOONeo5活力版手机做预热,公布了该手机的新特性,新款手机将配有3。5mm耳机孔,还支持环绕式立体双扬声器。据IT之家了解,iQO
新品种的新用法三星W215G使用手册人类科技的进步一直都是一个让人惊叹的话题。1973年4月9日的纽约曼哈顿街头,第一通手机电话被拨通,让路人驻足观望,标志着一个时代的开启。但那时的手机还只是个手持电话机,打电话是唯
比特币又上热搜马斯克一句话,比特币便上蹿下跳。近日,善变的特斯拉CEO马斯克又聊虚拟币。这次他称比特币能耗疯狂,他出于对环境的考虑,突然拒绝使用这种加密货币作为支付手段。用一张图表示了比特币过去
赵明6月份荣耀50首发骁龙778G芯片5月21日,2021高通技术与合作峰会正式拉开帷幕,荣耀终端CEO赵明受邀致辞。赵明提到,荣耀50系列将于6月发布,会搭载骁龙778G5G平台。赵明表示,荣耀独立以后,高通是首批合
3000元的预算,你会选择哪部手机?2021年20003000价位的手机真的是神仙打架,在2020年的时候,搭载高通骁龙865的旗舰手机普遍价格都在3000以上,而今年搭载了骁龙870这样不亚于最新旗舰芯片的手机都直