我想把一个InputStream is
转换为一个Stream<String> stream
,就像在将InputStream转换为Stream<String>给定一个字符集中一样。但这次,我不想按照换行符分割InputStream
,而是想将其分割成相等长度的部分。因此,流中所有字符串的长度都相同(最后一个元素可能会短一些)。
我想把一个InputStream is
转换为一个Stream<String> stream
,就像在将InputStream转换为Stream<String>给定一个字符集中一样。但这次,我不想按照换行符分割InputStream
,而是想将其分割成相等长度的部分。因此,流中所有字符串的长度都相同(最后一个元素可能会短一些)。
BufferedReader.lines
相同的模式执行操作:
InputStreamReader
- 首先创建一个 InputStreamReader。Iterator<String>
- 实现一个自定义 Iterator 子类,将流分成任意大小的块。您可能需要实现 hasNext()
和 next()
方法,调用 readPart()
方法来读取最多 N 个字符。Spliterators.spliteratorUnknownSize
- 将迭代器传递给此方法,以创建 Spliterator。StreamSupport.stream
- 将 Spliterator 传递给此方法,以创建一个流。这方面没有直接的支持。您可以创建一个简单的工厂方法:
static Stream<String> strings(InputStream is, Charset cs, int size) {
Reader r=new InputStreamReader(is, cs);
CharBuffer cb=CharBuffer.allocate(size);
return StreamSupport.stream(new Spliterators.AbstractSpliterator<String>(
Long.MAX_VALUE, Spliterator.ORDERED|Spliterator.NONNULL) {
public boolean tryAdvance(Consumer<? super String> action) {
try { while(cb.hasRemaining() && r.read(cb)>0); }
catch(IOException ex) { throw new UncheckedIOException(ex); }
cb.flip();
if(!cb.hasRemaining()) return false;
action.accept(cb.toString());
cb.clear();
return true;
}
}, false).onClose(()->{
try { r.close(); }catch(IOException ex) { throw new UncheckedIOException(ex); }
});
}
它可以像这样使用:
try(Stream<String> chunks=strings(is, StandardCharsets.UTF_8, 100)) {
// perform operation with chunks
}