David Doria
David Doria

Reputation: 10273

Copying from an InputStream to a BufferedOutputStream

I am sending a file over a socket and am trying to write it to a file at the receiver.

I've seen examples that do something like this:

int bytesRead = 0;
while (bytesRead != -1)
{
    bytesRead = networkInputStream.read(buffer, 0, diskBlockSizeEstimate);
    bufferedOutputStream.write(buffer, 0, bytesRead);
}

However, from http://developer.android.com/reference/java/io/InputStream.html#read%28byte[]%29 it souunds like .read returns -1 when the end of the stream is reached. Then when .write is called with -1, an exception is thrown. Do I have to implement logic that says "if(bytesRead==-1) set bytesToRead = fileSize - totalBytesRead" or something like this:

int fileSize = ... get filesize from sender ...;
int totalBytesRead = 0;
int bytesRead = 0;
while (bytesRead != -1)
{
    bytesRead = networkInputStream.read(buffer, 0, diskBlockSizeEstimate);
    if(bytesRead == -1)
    {
       bufferedOutputStream.write(buffer, 0, fileSize - totalBytesRead);
       totalBytesRead += fileSize - totalBytesRead;
    }
    else
    {
       bufferedOutputStream.write(buffer, 0, bytesRead);
       totalBytesRead += bytesRead;
    }
}

Also, would it be better to do while(totalBytesRead != fileSize) instead of while(bytesRead != -1) ?

Upvotes: 0

Views: 1919

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1502116

My typical loop for this sort of thing looks like this:

int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
    output.write(buffer, 0, bytesRead);
}

While I don't usually like performing an assignment within a condition (loop or if) this is a sufficiently common pattern for this particular use case that you get used to it very quickly.

Note that the read here is just for the whole buffer - I'm not sure why you'd want to limit it to diskBlockSizeEstimate... or if you do want that as the largest amount to read each time, just create the buffer with that size to start with.

Upvotes: 3

Related Questions