从字节序列创建InputStream的简短,巧妙的方法

时间:2016-04-27 20:30:44

标签: java arrays byte sequence java-stream

我想要InputStream一个字节序列:012,... 255

我当然可以创建一个new byte[0x100],创建一个int的循环,并将int值填充到byte(不要让我开始使用Java签名的byte类型),然后从中创建ByteArrayInputStream

但是使用Java 8肯定会有更好,更紧凑,更聪明的方式。诀窍似乎是生成字节数组。我发现elsewhere intfinal int[] values = IntStream.range(0, 0x100).toArray(); 一样简单,如下所示:

byte

但我需要一个ByteStream数组,而且没有IntStream。也许有一个int集合函数可以将byte[]值收集到Ractive.DEBUG = /unminified/.test(function() {/*unminified*/});数组中?或者更聪明的东西?

4 个答案:

答案 0 :(得分:1)

您可以声明byte[],然后使用带有IntStream的{​​{1}}来填充它。像

这样的东西
forEach

答案 1 :(得分:0)

循环会更快,但是如果你要求讨论如何使用流来解决它,你可以在guava byte[] bytes = IntStream.range(0, 0x100) .mapToObj(i -> (byte) i) // boxes into a Byte .collect(Collectors.collectingAndThen(Collectors.toList(), Bytes::toArray)) api的帮助下做到这一点:

telnet localhost 5554

在这个例子中,每个int都包含在一个Byte中,它被收集到List中,然后转换为byte []。

这种方法的优点是它可以在不事先知道目标数组的大小的情况下工作。如果您知道数组的大小,@ ElliotFrisch的答案会更有效率,并且循环效率更高。

答案 2 :(得分:0)

没有Arrays.setAll的字节版本,这太糟糕了。它会像这样工作:

byte[] foo = new byte[0x100];
setAll(foo, i -> i++);

如果有人真的想要它,他们可以使用这个,改编自intArrays.setAll

public static void setAll(byte[] array, IntUnaryOperator generator) {
    Objects.requireNonNull(generator);
    for (int i = 0; i < array.length; i++)
        array[i] = (byte)generator.applyAsInt(i);
}

答案 3 :(得分:0)

如果您想从InputStream创建延迟IntStream(仅使用最低有效字节),您可以尝试这样做:

public static InputStream asByteInputStream(IntStream is) {
    Spliterator.OfInt spltr = is.spliterator();
    return new InputStream() {
        private int last;

        @Override
        public int read() {
            return spltr.tryAdvance((int val) -> last = val) ? (last & 0xFF) : -1;
        }

        @Override
        public void close() {
            is.close();
        }
    };
}

使用测试:

AtomicBoolean flag = new AtomicBoolean(false);
InputStream is = asByteInputStream(IntStream.range(0, 256).onClose(() -> flag.set(true)));
byte[] data = new byte[256];
assertEquals(2, is.skip(2));
// read 3..255 into data[0..253]
assertEquals(254, is.read(data));
// nothing more in the input
assertEquals(-1, is.read());
for(int i=0; i<254; i++) {
    assertEquals((byte)(i+2), data[i]);
}
assertEquals(0, data[254]);
assertEquals(0, data[255]);

// close is forwarded to original IntStream
assertFalse(flag.get());
is.close();
assertTrue(flag.get());