Available bytes in InputStream

Hello JGO,

I would like some suggestions for a fast and reliable way of getting the available bytes in an inputstream.

InputStream.available()

doesn’t return the correct value.

I have found a way, but for me it looks really inefficient:


			//"is" is the InputStream
			is.mark(Integer.MAX_VALUE);
			long filesize = 0;
			int len;
			byte[] buffer = new byte[1024];
			while((len = is.read(buffer)) != -1) {
				filesize+= len;
			}
			is.reset();

Any suggestions/improvements are welcome

It returns the right value, just read the specs.

It returns the right value after I’ve executed the code I posted, but before that, it returns much less.


			System.out.println(is.available());
			is.mark(Integer.MAX_VALUE);
			long filesize = 0;
			int len;
			byte[] buffer = new byte[1024];
			while((len = is.read(buffer)) != -1) {
				filesize+= len;
			}
			is.reset();
			System.out.println(is.available() + " is " + filesize);

The log:


8192
168262 is 168262

Read the spec, I tell you.

Yeah, Riven’s right. Read the spec. :stuck_out_tongue:

this?

If you mean that, I’ve read it many times, but still don’t see a solution

I put the question wrong: Available bytes in InputStream should be total number of bytes in InputStream. :wink:
Like downloading a file, how to get the size of that file?

Parse the HTTP header

If you want the size of an actual [icode]File[/icode], [icode]Files.size()[/icode] works on Java 7+.

You can’t really know how large a raw InputStream is until you’ve read it, it could be infinite for all the code knows, hence the name Stream.
You can either measure something that has a known finite and determined size (e.g. a File), or you can attempt to infer the data from elsewhere (e.g. the HTTP header).

HTTP headers may still not deliver the desired information under certain circumstances such as when Chunked Transfer Encoding is used.

Yeah sure, but Kefwar was talking about file downloads, in which case it is safe to assume the Content-Length line is defined.

Thanks for the suggestion, I’ve worked it out and it works.
But since I’m already requesting an information file from the server, I’ll add the filesize in that file. This way I can still use FTP protocol.

EDIT: for those who are interested in it, here is the code:


	private int contentLength(URL url) {
		HttpURLConnection connection;
		int contentLength = -1;

		try {
			HttpURLConnection.setFollowRedirects(false);

			connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("HEAD");

			contentLength = connection.getContentLength();
		} catch (Exception e) {
		}

		return contentLength;
	}

Just to be snarky. Not only does the docs clearly state the meaning of the result…it also matches the English def of the word available.