在 Java 中处理跨不同源的输入数据时,我们有时会遇到必须通过将InputStream中的数据转换为Stream来处理数据的情况。
在本教程中,我们将了解实现此转换的不同方法。
使用BufferedReader和lines()方法进行转换
将InputStream转换为Stream 的一种有效方法是使用BufferedReader及其lines()方法。
首先,我们将定义一个包含文本行序列的字节数组bytes :
byte[] bytes = "Hello\nWorld\nThis\nis\na\ntest".getBytes(StandardCharsets.UTF_8); InputStream inputStream = new ByteArrayInputStream(bytes);
|
在提供的代码块中,我们创建一个名为bytes的字节数组来保存所提供文本行的UTF-8编码表示形式。然后,我们使用ByteArrayInputStream(bytes)从该字节数组创建一个名为inputStream 的输入流。
此设置允许我们模拟包含指定文本的InputStream,该文本将在后续示例中用于转换为Stream。
现在,让我们看看如何在测试场景中实现这种方法:
@Test void givenInputStream_whenConvertingWithBufferedReader_thenConvertInputStreamToStringStream() throws IOException { try (InputStreamReader isr = new InputStreamReader(inputStream, StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(isr)) { Stream<String> stringStream = reader.lines(); String result = stringStream.reduce("", (s1, s2) -> s1 + s2); assertEquals("HelloWorldThisisatest", result); } }
|
在上面的示例中,我们使用InputStreamReader创建一个包裹在InputStream周围的BufferedReader对象。这使我们能够从InputStream中有效地读取文本行。此外,BufferedReader的lines()方法返回一个包含从输入读取的行的Stream 。最后,我们处理这个Stream ,使用reduce()操作将所有String元素连接成一个结果String,随后我们使用断言根据预期内容进行验证。
请注意,我们利用try-with-resources来确保InputStreamReader和BufferedReader在try块结束时自动关闭,从而释放相关资源。
使用Scanner转换
另一种方法涉及使用Scanner来标记InputStream。让我们看一个简单的实现:
@Test void givenInputStream_whenConvertingWithScannerFindAll_thenConvertInputStreamToStringStream() { try (Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8)) { Stream<String> stringStream = scanner.findAll(".+") .map(MatchResult::group); String result = stringStream.collect(Collectors.joining()); assertEquals("HelloWorldThisisatest", result); } }
|
在此方法中,我们使用InputStream初始化Scanner对象,并将其配置为使用StandardCharsets.UTF_8进行 UTF-8 编码。
然后,我们使用带有正则表达式模式“ .+ ”的 findAll()方法来匹配一个或多个字符,有效地将InputStream的内容捕获为一系列MatchResult。
然后,我们使用MatchResult::group将每个匹配结果映射到其匹配组,从而生成包含匹配字符串的Stream 。随后,我们使用Collectors.joining()方法将Stream中的所有字符串连接成一个名为result 的字符串。