question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RFE: Add a public ByteStreams.toByteArray(InputStream in, int expectedSize)

See original GitHub issue
  1. rename the current package-private ByteStreams.toByteArray(InputStream in, int expectedSize)

  2. add public ByteStreams.toByteArray(InputStream in, long expectedSize) that does exactly this: https://github.com/google/guava/blob/e102fa4a86dad34f375e06c8ce0f52ea264588c3/guava/src/com/google/common/io/Files.java#L159-L175

  3. except that this line: https://github.com/google/guava/blob/e102fa4a86dad34f375e06c8ce0f52ea264588c3/guava/src/com/google/common/io/Files.java#L172 should be: return expectedSize <= 0

  4. remove package-private Files.readFile(InputStream in, long expectedSize)

rationale for 2):

it is impossible to efficiently read an input stream of known size to a byte array, but sometimes it is needed. example a): efficiently reading a binary file after checking that its header is valid. only options are: reading the header, closing the file, open it again and read it fully with Files.readFile(...). or: reading the header then passing the stream to inefficient ByteStreams.toByteArray(InputStream in). example b): reading an InputStream of a zip file’s ZipEntry, where again the uncompress length is known ahead of time.

both examples a) and b) are from real code i am wirting.

rationale for 3):

ZipFile entry returns -1 rather than 0 for unknown lengths: https://docs.oracle.com/javase/8/docs/api/index.html?java/util/zip/ZipEntry.html Given that 0 is a valid length, that makes total sense. so it also makes sense that expectedSize should handle <0 values (and 0 too) as unknown lengths.

(rationales for 1) and 4) are obvious.)

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:13 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
Lanchoncommented, Jun 30, 2018

i also want to comment on this:

In most other cases, people either:

  • know the exact length (in which case they can use ByteStreams.readFully)

ByteStreams.readFully is not an option. it will throw if the file is shorter than expected, but it will silently fail (misbehave) if the file length was increased under its feet, potentially returning a byte array that is not representative of any file state.

what is needed is a performance hint to a robust helper, not some brittle alternative that you cannot justify choosing solely on the grounds of increased performance. i will keep rolling my code for this as guava does not provide useful help for this case.

the fact that you actually need this yourself and do not share it is frustrating.

1reaction
cpovirkcommented, Mar 15, 2018

I don’t know if this will make you feel better or worse, but we dedicated a couple engineer hours to discussing this over the past couple days, and we’ll probably spend a couple more on it in the next week or so. I can’t speak for everyone, by my main reservation is that ZipFile seems to be the main use case: In most other cases, people either:

  • won’t have opened the stream yet (in which case they can implement ByteSource and get this behavior for free once we make the appropriate optimization there)
  • won’t care about allocations, or will care about allocations enough to read the file in chunks
  • know the exact length (in which case they can use ByteStreams.readFully)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Java InputStream to Byte Array and ByteBuffer - Baeldung
In this quick tutorial, we're going to take a look at how to convert an InputStream to a byte[] and ByteBuffer – first...
Read more >
Convert InputStream to byte array in Java - Stack Overflow
Use vanilla Java's DataInputStream and its readFully Method (exists since at least Java 1.4): ... byte[] bytes = new byte[(int) file.length()]; ...
Read more >
org.apache.poi.util.IOUtils.toByteArray java code examples
public static byte[] toByteArray(InputStream stream, final int length) throws IOException { return toByteArray(stream, length, Integer.MAX_VALUE);
Read more >
ByteStreams (Guava: Google Core Libraries for Java 19.0 API)
toByteArray. public static byte[] toByteArray(InputStream in) throws IOException. Reads all bytes from an input stream into a byte array. Does not close ...
Read more >
com.google.common.io.ByteStreams Maven / Gradle / Ivy
private static byte[] toByteArrayInternal(InputStream in, Deque bufs, int totalLen) throws IOException { // Starting with an 8k buffer, double the size of ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found