12

I'm running into a strange problem while reading from an InputStream on the Android platform. I'm not sure if this is an Android specific issue, or something I'm doing wrong in general.

The only thing that is Android specific is this call:

InputStream is = getResources().openRawResource(R.raw.myfile);

This returns an InputStream for a file from the Android assets. Anyways, here's where I run into the issue:

bytes[] buffer = new bytes[2];
is.read(buffer);

When the read() executes it throws an IOException. The weird thing is that if I do two sequential single byte reads (or any number of single byte reads), there is no exception. In example, this works:

byte buffer;
buffer = (byte)buffer.read();
buffer = (byte)buffer.read();

Any idea why two sequential single byte reads work but one call to read both at once throws an exception? The InputStream seems fine... is.available() returns over a million bytes (as it should).

Stack trace shows these lines just before the InputStream.read():

java.io.IOException
at android.content.res.AssetManager.readAsset(Native Method)
at android.content.res.AssetManager.access$800(AssetManager.java:36)
at android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:542)

Changing the buffer size to a single byte still throws the error. It looks like the exception is only raised when reading into a byte array.

If I truncate the file to 100,000 bytes (file is: 1,917,408 bytes originally) it works fine. Is there a problem with files over a certain size?

Any help is appreciated!
Thanks!

CSchulz
  • 10,882
  • 11
  • 60
  • 114
DJayC
  • 1,765
  • 3
  • 12
  • 10
  • A 1mb file worked, but a 1.5mb file did not. Is there some size restriction for assets?? – DJayC Aug 13 '09 at 19:36

4 Answers4

14

(my post to android-developers isn't showing up, so I'll try reposting it here)

IIRC, this problem comes from trying to access files that were compressed as part of building the APK.

Hence, to work around the issue, give it a file extension that won't be compressed. I forget the list of what extensions are skipped, but file types known to already be compressed (e.g., mp3, jpg) may work.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    You're absolutely right. Renaming the extension to .MP3 worked. This is a silly bug, and there should be a way to tell it to not compress a certain file if it's going to cause this type of issue. Thanks – DJayC Aug 13 '09 at 21:48
  • @ CommonsWare:Are there any other methods to read compressed file from asset? I mean file be compressed during packaging intoAPK but we can read asset file? – VSB Oct 06 '13 at 08:27
3

Changing the file extension to .mp3 to avoid the file compression does work, but the APK of the app is much bigger (in my case 2.3 MB instead of 0.99 MB).

Is there any other way to avoid this issue ?

Here is my answer: Load files bigger than 1M from assets folder

Community
  • 1
  • 1
mmathieum
  • 506
  • 5
  • 14
2

You can compress the file for yourself with GZIP and unpack it with GZIPInputStream class.

http://developer.android.com/reference/java/util/zip/GZIPInputStream.html

Marcus
  • 21
  • 1
  • using GZIP by your hint i implemented a sample code [here](http://stackoverflow.com/a/19207150/1080355) – VSB Oct 06 '13 at 09:07
0

You are correct, in that there is a certain size limit for extracting files. You may wish to split larger files into 1MB pieces, and have a method by which you know which files are made of which pieces, stitching them back together again when your app runs.

vol
  • 1,533
  • 3
  • 13
  • 18