15

I have a FileInputStream created using Context.openFileInput(). I now want to convert the file into a byte array.

Unfortunately, I can't determine the size of the byte array required for FileInputStream.read(byte[]). The available() method doesn't work, and I can't create a File to check it's length using the specific pathname, probably because the path is inaccessible to non-root users.

I read about ByteArrayOutputStream, and it seems to dynamically adjust the byte array size to fit, but I can't get how to read from the FileInputStream to write to the ByteArrayOutputStream.

2
  • possible duplicate of Android - getting from a Uri to an InputStream to a byte array? Commented Mar 17, 2011 at 1:43
  • 2
    The byte[] you supply to read(byte[]) isn't intended to be the full size of whatever it is you're trying to read. It's a buffer that can hold the maximum number of bytes you're willing to read at a time, and each call to read will put some number of bytes into that buffer and return a number telling you how many bytes it put. Commented Mar 17, 2011 at 1:52

4 Answers 4

46

This should work.

InputStream is = Context.openFileInput(someFileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
while ((int bytesRead = is.read(b)) != -1) {
   bos.write(b, 0, bytesRead);
}
byte[] bytes = bos.toByteArray();
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, I solved with another method though. while(is .available>0){ bos.write(is.read()) }
@Jeremy: Robby's method is the standard way of doing this in Java. His reads the input up to 1024 bytes at a time... yours reads it 1 byte at a time. I'd advise using his suggestion.
@Mihir May I ask, what do you mean by "this method will work only in rooted device."? Does that mean Robby's method isn't applicable in rooted devices (Android, embedded operating systems, etc.) or devices that are S_OFF or rooted (Specifcally devices mentioned in XDA forums)? Or do you mean that Jeremy's method is suitable for Android?
Should close the ByteArrayOutputStream like bos.close();
@MuhammadBabar as far as I can see the close() method has no effect.
|
9

This is the easiest way

FileInputStream fis =  openFileInput(fileName);

byte[] buffer =   new byte[(int) fis.getChannel().size()];

fis.read(buffer);

1 Comment

Please note openFileInput method doesn't accept path separators. So instead of openFileInput, you can use fis = new FileInputStream (new File(filename_with_path));
1

You can pre-allocate the byte array using

int size = context.getFileStreamPath(filename).length();

This way, you will avoid allocating memory chunks every time your ByteArrayOutputStream fills up.

Comments

0

For the method to work on any device and aplication you just need to replace:

InputStream is = Context.getContentResolver().openInputStream(yourFileURi);

This way you can encode external files as well.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.