从 InputStream 创建 java.util.stream.Stream 的最佳方法是什么?
What is the best way to create a java.util.stream.Stream from an InputStream?
据我了解,InputStream
是一个字节流。我有兴趣将 InputStream 对象转换为字节流。基本上,以下方法的实现。
public Stream<byte[]> toStream(final InputStream is, final int bufferSize);
完成这项工作的最佳方法是什么?缓冲区大小是一次从 InputStream 读取的字节数。
你需要自己写 Spliterator
,像这样:
public final class ChunkingInputStreamSpliterator implements Spliterator<byte[]> {
private final InputStream is;
private final int bufferSize;
public ChunkingInputStreamSpliterator(InputStream is, int bufferSize) {
this.is = is;
this.bufferSize = bufferSize;
}
@Override
public boolean tryAdvance(Consumer<? super byte[]> action) {
byte[] bytes;
try {
bytes = this.is.readNBytes(this.bufferSize);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
if (bytes.length == 0)
return false;
action.accept(bytes);
return true;
}
@Override
public Spliterator<byte[]> trySplit() {
return null; // cannot split an InputStream
}
@Override
public long estimateSize() {
return Long.MAX_VALUE; // unknown
}
@Override
public int characteristics() {
return Spliterator.ORDERED | Spliterator.NONNULL;
}
}
然后像这样实现你的方法:
public static Stream<byte[]> toStream(InputStream is, int bufferSize) {
return StreamSupport.stream(new ChunkingInputStreamSpliterator(is, bufferSize), false);
}
如果你没有Java 11,所以你没有非常方便的readNBytes
方法,那么你自己做这部分:
public boolean tryAdvance(Consumer<? super byte[]> action) {
byte[] bytes = new byte[this.bufferSize];
int len = 0;
try {
for (int read; len < bytes.length; len += read)
if ((read = this.is.read(bytes, len, bytes.length - len)) <= 0)
break;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
if (len == 0)
return false;
if (len < bytes.length)
bytes = Arrays.copyOfRange(bytes, 0, len);
action.accept(bytes);
return true;
}
据我了解,InputStream
是一个字节流。我有兴趣将 InputStream 对象转换为字节流。基本上,以下方法的实现。
public Stream<byte[]> toStream(final InputStream is, final int bufferSize);
完成这项工作的最佳方法是什么?缓冲区大小是一次从 InputStream 读取的字节数。
你需要自己写 Spliterator
,像这样:
public final class ChunkingInputStreamSpliterator implements Spliterator<byte[]> {
private final InputStream is;
private final int bufferSize;
public ChunkingInputStreamSpliterator(InputStream is, int bufferSize) {
this.is = is;
this.bufferSize = bufferSize;
}
@Override
public boolean tryAdvance(Consumer<? super byte[]> action) {
byte[] bytes;
try {
bytes = this.is.readNBytes(this.bufferSize);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
if (bytes.length == 0)
return false;
action.accept(bytes);
return true;
}
@Override
public Spliterator<byte[]> trySplit() {
return null; // cannot split an InputStream
}
@Override
public long estimateSize() {
return Long.MAX_VALUE; // unknown
}
@Override
public int characteristics() {
return Spliterator.ORDERED | Spliterator.NONNULL;
}
}
然后像这样实现你的方法:
public static Stream<byte[]> toStream(InputStream is, int bufferSize) {
return StreamSupport.stream(new ChunkingInputStreamSpliterator(is, bufferSize), false);
}
如果你没有Java 11,所以你没有非常方便的readNBytes
方法,那么你自己做这部分:
public boolean tryAdvance(Consumer<? super byte[]> action) {
byte[] bytes = new byte[this.bufferSize];
int len = 0;
try {
for (int read; len < bytes.length; len += read)
if ((read = this.is.read(bytes, len, bytes.length - len)) <= 0)
break;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
if (len == 0)
return false;
if (len < bytes.length)
bytes = Arrays.copyOfRange(bytes, 0, len);
action.accept(bytes);
return true;
}