Is there a concise way to create an InputSupplier for an InputStream in Google Guava?

后端 未结 3 1185
被撕碎了的回忆
被撕碎了的回忆 2021-02-12 22:07

There are a few factory methods in Google Guava to create InputSuppliers, e.g. from a byte[]:

ByteStreams.newInputStreamSupplier(bytes);


        
相关标签:
3条回答
  • 2021-02-12 22:33

    No, I haven't seen anything.
    I think you have found the best way.
    The only alternative where to store the inputstream in a byte array or a file and create a Supplier with ByteStreams.newInputStreamSupplier() or Files.newInputStreamSupplier(), but I would discourage to do like that.
    You could also use

    public static long copy(InputStream from, OutputStream to)
    from
    ByteStreams
    see:src

    0 讨论(0)
  • 2021-02-12 22:42

    That would be as wrong as wrapping an Iterator to an Iterable, I feel there is like zero probability of such a thing going into the library. As elou says, you can use ByteStreams.copy() method, but there doesn't seem to be an obvious reason to do equals() on two streams.

    I understand guava authors hesitation to add such a (trivial) method - how common can it be to fully (or partially, but without knowing where the stream was left, so it's as good as unusable thereafter) read two streams just to see if they are the same, without any other processing of the data? Do these bytes come from a non-repeatable-read source, like a network socket? Otherwise, if it is just a file somewhere, or an in-memory byte array, there are other ways that lend themselves to do an equality test.

    0 讨论(0)
  • 2021-02-12 22:49

    There's no way to convert an arbitrary InputStream into an InputSupplier<InputStream>, because an InputSupplier<InputStream> is supposed to be an object that can create a fresh, new InputStream every time its getInput() method is called. This is only possible when the underlying source of bytes is available for re-use; hence the factory methods that take a byte[] or File and return an InputSupplier<InputStream>.

    As Dimitris suggests, InputSupplier relates to InputStream in the same way that Iterable relates to Iterator. The anonymous class you describe is incorrect because it returns the same stream every time getInput() is called, so subsequent invocations will return an InputStream that is already exhausted and closed.

    Here is another problem with your anonymous class: part of the motivation for InputSupplier is to limit the visibility of the actual InputStream so that it can be closed automatically. If you wrap an externally-visible InputStream in an InputSupplier and then pass that into a utility method, the utility method may close your InputStream. You might be OK with that but that's not a clean usage pattern that Guava would want to promote.

    When I found myself wanting to do the same thing, I realized I was doing it backwards. Instead of doing this:

    Files.copy(InputSupplier.of(inputStream), destinationFile);
    

    (doesn't exist), I should instead be doing this:

    ByteStreams.copy(inputStream, Files.newOutputStreamSupplier(destinationFile));
    
    0 讨论(0)
提交回复
热议问题