Like in Convert InputStream into Stream<String> given a Charset I want to convert an InputStream is
into a Stream<String> stream
. But this time instead of splitting the InputStream
at the new line characters, I want to split it into parts of equal length. So all strings of the stream would have the same length (with a possible exception on the last element of the stream, that may be shorter).
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
I don't think this is possible using class library methods only, so you'll have to write your own logic that follows the same pattern as BufferedReader.lines
:
InputStreamReader
- Start by creating an InputStreamReaderIterator<String>
- Implement a custom Iterator subclass that splits the stream into pieces however you want. It sounds like you want to implementhasNext()
andnext()
to call areadPart()
that reads at most N characters.Spliterators.spliteratorUnknownSize
- Pass the iterator to this method to create a Spliterator.StreamSupport.stream
- Pass the Spliterator to this method to create a stream.
Ultimately, the class library just doesn't have builtins for reading from an input stream and converting into fixed-size strings, so you have to write those for #1/#2. After that, converting to a stream in #3/#4 isn't too bad since there are class library methods to help.
回答2:
There is no direct support for this. You can create a straight-forward factory method:
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); }
});
}
It can be used like:
try(Stream<String> chunks=strings(is, StandardCharsets.UTF_8, 100)) {
// perform operation with chunks
}