Skip to content

Commit

Permalink
Add a method to read an entire file or stream into a byte array, and …
Browse files Browse the repository at this point in the history
…tests for it.
  • Loading branch information
nishihatapalmer committed Apr 11, 2016
1 parent b97e9a2 commit 481aaa9
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/main/java/net/byteseek/io/IOUtils.java
Expand Up @@ -32,6 +32,8 @@
package net.byteseek.io;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
* A static utility package containing some useful methods for reading and
Expand Down Expand Up @@ -78,6 +80,52 @@ public static byte[] readEntireFile(final File file) throws IOException {
return result;
}

/**
* Reads an input stream and returns a single array of bytes containing the stream contents.
* <p>
* The implementation builds a list of byte array buffers, then copies them into a single
* byte array. This will use a bit more than twice as much memory as the length of the stream.
* <p>
* The input stream is not closed when finished reading - that remains the responsibility of the
* code which passes it in.
*
* @param input The input stream to read.
* @return A byte array containing the stream contents.
* @throws IOException If there is any problem reading from the InputStream.
*/
public static byte[] readEntireStream(final InputStream input) throws IOException {
final int BUFFER_SIZE = 4096;

// Read the stream into a list of byte buffers and calculate the length:
// Only place byte arrays the size of the buffer on to the list; retain the
// last buffer and how many bytes it represents.
final List<byte[]> bufferList = new ArrayList<byte[]>();
byte[] buffer = new byte[BUFFER_SIZE];
int totalRead = 0;
int bytesRead;
while ((bytesRead = readBytes(input, buffer)) == BUFFER_SIZE) {
totalRead += BUFFER_SIZE;
bufferList.add(buffer);
buffer = new byte[BUFFER_SIZE];
}
totalRead += bytesRead;

// Write the byte buffers into a single byte array, now we know the length.
// Process the list first, which are always the size of byte buffers,
// then add the final buffer, which may be smaller than that.
final byte[] result = new byte[totalRead];
final int numBuffers = bufferList.size();
int totalWritten = 0;
for (int bufferIndex = 0; bufferIndex < numBuffers; bufferIndex++) {
final byte[] bufferToWrite = bufferList.get(bufferIndex);
System.arraycopy(bufferToWrite, 0, result, totalWritten, BUFFER_SIZE);
totalWritten += BUFFER_SIZE;
}
System.arraycopy(buffer, 0, result, totalWritten, bytesRead);

return result;
}

/**
* Reads bytes from an {@link java.io.InputStream} into the byte array,
* until the byte array is filled or there are no more bytes in the stream.
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/net/byteseek/io/IOUtilsTest.java
Expand Up @@ -34,6 +34,23 @@ private void testReadEntireFile(File file) throws Exception {
assertFileBytesEqual(file, asciiFileArray);
}

@Test
public void testReadEntireStream() throws Exception {
testReadEntireStream(asciiFile);
testReadEntireStream(zipFile);
}

private void testReadEntireStream(File file) throws Exception {
InputStream input = new FileInputStream(file);
try {
byte[] array = IOUtils.readEntireStream(input);
assertEquals("Read correct size", file.length(), array.length);
assertFileBytesEqual(file, array);
} finally {
input.close();
}
}


@Test
public void testReadBytes() throws Exception {
Expand Down

0 comments on commit 481aaa9

Please sign in to comment.