My solution looks like this:
public static final byte[] readBytes (InputStream in, int maxBytes) throws IOException { byte[] result = new byte[maxBytes]; int bytesRead = in.read (result); if (bytesRead > maxBytes) { throw new IOException ("Reached max bytes (" + maxBytes + ")"); } if (bytesRead < 0) { result = new byte[0]; } else { byte[] tmp = new byte[bytesRead]; System.arraycopy (result, 0, tmp, 0, bytesRead); result = tmp; } return result; }
EDIT: New variant
public static final byte[] readBytes (InputStream in, int bufferSize, int maxBytes) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[bufferSize]; int bytesRead = in.read (buffer); out.write (buffer, 0, bytesRead); while (bytesRead >= 0) { if (maxBytes > 0 && out.size() > maxBytes) { String message = "Reached max bytes (" + maxBytes + ")"; log.trace (message); throw new IOException (message); } bytesRead = in.read (buffer); if (bytesRead < 0) break; out.write (buffer, 0, bytesRead); } return out.toByteArray(); }
available()doesn't do what you're looking for. There is an explicit warning in the Javadoc against using it as the number of bytes remaining in the stream. That's not what it's for. Your problem isn't difficult. You can just keep track of the accumulated read count and abort when it gets too high.