Reputation: 1658
I currently use the following to read a bluetooth inputstream and save it as a file. It works well with small files but then with larger files its creating a large byte array first. Whats the most efficient way of doing this AND making sure that it reads the only the length specified, no more, no less?
public void getAndWrite(InputStream is, long length, String filename)
throws IOException {
// Create the byte array to hold the data
byte[] bytes = new byte[(int) length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read stream ");
}
// Write the byte array to file
FileOutputStream fos = null;
try {
fos = mContext.openFileOutput(filename, Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
Log.e(TAG, "Problem finding internal storage", e);
}
try {
fos.write(bytes);
fos.close();
} catch (IOException e) {
Log.e(TAG, "Problem writing file", e);
}
}
Upvotes: 1
Views: 1533
Reputation: 692161
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int remaining = length;
int read = 0;
while (remaining > 0
&& (read = in.read(buffer, 0, Math.min(remaining, bufferSize))) >= 0) {
out.write(buffer, 0, read);
remaining -= read;
}
Note that the above makes sure you don't write more that length bytes. But it doesn't make sure you write exactly length bytes. I don't see how you could do this without reading length bytes in memory, or reading length bytes and writing to a temp file, then writing the temp file to the final destination.
Upvotes: 2