1

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);
        }
    }
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
7wonders
  • 1,639
  • 1
  • 17
  • 34
  • 1
    This will cause you heap problems, as you are trying to read the whole thing into memory. Open your `FileOutputStream` and write to it as you read, in larger chunks than ~1K. See http://stackoverflow.com/a/43163/115145 – CommonsWare May 28 '12 at 19:53

1 Answers1

2
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.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255