如何将java.io.ObjectInputStream转换为java.util.stream.Stream?

时间:2014-12-08 01:15:50

标签: java java-8 inputstream java-io java-stream

是否有一种直接的方式将java.io.ObjectInputStreamjava.util.stream.Stream一起使用?

似乎提供了java.io.BufferedReader.lines来将缓冲的阅读器转换为Stream,但似乎没有Object的等价物。

有没有人有这个转换的好解决方案?

2 个答案:

答案 0 :(得分:4)

ObjectInputStream可以读取比Objects更多的内容。该类实现了DataInput,因此它可以读取各种数据。然后是readUnshared之类的特殊方法。因此,Stream将是ObjectInputStream功能的一个非常有限的子集。

但是如果你只想逐个阅读对象,你可以编写自己的方法:

public Stream<Object> toStream(final ObjectInputStream stream) {
    return Stream.generate(() -> readObject(stream)).onClose(
        () -> close(stream));
}

private static Object readObject(ObjectInputStream stream) {
    try {
        return stream.readObject();
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

private static void close(Closeable c) {
    try {
        c.close();
    } catch (IOException e) {
        logger.log(Level.WARNING, "Couldn't close " + c, e);
    }
}

你甚至可以有一个打字的流:

public <T> Stream<T> toStream(final ObjectInputStream stream,
                              final Class<T> cls) {
    return Stream.generate(() -> cls.cast(readObject(stream))).onClose(
        () -> close(stream));
}

答案 1 :(得分:0)

此解决方案生成有限流而不会在末尾抛出EOFException。它还会在最后优雅地关闭流。我必须实现一个Spliterator,它尝试读取hasNext()并返回next()上读取的元素。

public static <T> Stream<T> toStream(final ObjectInputStream stream,
                              final Class<T> cls) {

    Spliterator<T> spliterator = Spliterators.spliteratorUnknownSize(new Iterator<T>() {

        private T next;
        private boolean read = false;

        @Override
        public boolean hasNext() {
            if (!read) {
                try {
                    next = cls.cast(stream.readUnshared());
                } catch (EOFException e) {
                    next = null;
                } catch (ClassNotFoundException e) {
                    throw new RuntimeException(e);
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
                read = true;
            }
            return next != null;
        }

        @Override
        public T next() {
            read = false;
            return next;
        }
    }, Spliterator.DISTINCT | Spliterator.IMMUTABLE |
            Spliterator.ORDERED | Spliterator.NONNULL);

    return StreamSupport.stream(spliterator, false).onClose(() -> {
        try {
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    });
}