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. Ie, this works:
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.
> 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. Ie, this works:
> 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?
> On Aug 13, 10:36 am, Jonathan <jon.aposto...@gmail.com> wrote:
> > 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. Ie, this works:
> > 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.
> I was able to load a 1MB file okay, but 1.5MB crashed.
> On Aug 13, 12:30 pm, Jonathan <jon.aposto...@gmail.com> wrote:
> > 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?
> > On Aug 13, 10:36 am, Jonathan <jon.aposto...@gmail.com> wrote:
> > > 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:
> > > 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. Ie, this works:
> > > 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.
Is that a restriction on InputStream, or for assets? I was able to
include an MP3 file as a resource and it would play just fine
(although I didn't open it via InputStream)... the MP3 was about 3mb.
On Aug 13, 12:46 pm, Andrei <gml...@gmail.com> wrote:
> 1048576 is the file limit
> If you have bigger file split it
> On Aug 13, 3:35 pm, Jonathan <jon.aposto...@gmail.com> wrote:
> > I was able to load a 1MB file okay, but 1.5MB crashed.
> > On Aug 13, 12:30 pm, Jonathan <jon.aposto...@gmail.com> wrote:
> > > 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?
> > > On Aug 13, 10:36 am, Jonathan <jon.aposto...@gmail.com> wrote:
> > > > 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:
> > > > 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. Ie, this works:
> > > > 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.
I'm not exactly sure... I'm actually only reading the file 24 bytes at
a time, so I'm not quite sure why the IOException is thrown. I'm
never allocating a buffer for the full file.
If I do two sequential one byte reads it's fine... but a single 2 byte
read (using read(byte[])) it throws the exception. The exception is
thrown by AssetManager.readAsset.
On Aug 13, 2:09 pm, Jason Proctor <jason.android.li...@gmail.com>
wrote:
yeah, looking at AssetManager.java, read() calls native readAssetChar(), whereas read(byte[]) calls native readAsset(). readAsset() throws the IOException if the underlying Asset.read() returns negative. readAssetChar() just returns negative if the read() fails, no throw.
Asset.h has UNCOMPRESS_DATA_MAX set to a megabyte in the Android case, which might be a clue. AFAICS UNCOMPRESS_DATA_MAX isn't referenced anywhere else in the core code though (?).
i can't spend any more time digging right now. can someone from the droid team comment? i don't really want my application falling over at a future date because some asset went over a megabyte. which is quite likely.
>I'm not exactly sure... I'm actually only reading the file 24 bytes at
>a time, so I'm not quite sure why the IOException is thrown. I'm
>never allocating a buffer for the full file.
>If I do two sequential one byte reads it's fine... but a single 2 byte
>read (using read(byte[])) it throws the exception. The exception is
>thrown by AssetManager.readAsset.
>On Aug 13, 2:09 pm, Jason Proctor <jason.android.li...@gmail.com>
>wrote:
>> why is there a 1mb file limit in this case?
>> and is the restriction 1mb in the amount of stuff read, or in the
>> size of the file?
>> could you maybe open the file, skip a megabyte, then continue to read
>> the second megabyte?
>> >1048576 is the file limit
>> >If you have bigger file split it
Someone on StackOverflow responded to my question there and mentioned
it's a problem with compressed files. If the file is stored
uncompressed it works. In order to do this (per their suggestion) I
renamed my file to .mp3, which is a known compressed format to
android, and the reads work.
It sounds like we need a way to specify these formats ourself, or to
force a file to not be compressed during the packaging process.
Either that or lift the 1MB restriction.
On Aug 13, 2:25 pm, Jason Proctor <jason.android.li...@gmail.com>
wrote:
> yeah, looking at AssetManager.java, read() calls native
> readAssetChar(), whereas read(byte[]) calls native readAsset().
> readAsset() throws the IOException if the underlying Asset.read()
> returns negative. readAssetChar() just returns negative if the read()
> fails, no throw.
> Asset.h has UNCOMPRESS_DATA_MAX set to a megabyte in the Android
> case, which might be a clue. AFAICS UNCOMPRESS_DATA_MAX isn't
> referenced anywhere else in the core code though (?).
> i can't spend any more time digging right now. can someone from the
> droid team comment? i don't really want my application falling over
> at a future date because some asset went over a megabyte. which is
> quite likely.
> >I'm not exactly sure... I'm actually only reading the file 24 bytes at
> >a time, so I'm not quite sure why the IOException is thrown. I'm
> >never allocating a buffer for the full file.
> >If I do two sequential one byte reads it's fine... but a single 2 byte
> >read (using read(byte[])) it throws the exception. The exception is
> >thrown by AssetManager.readAsset.
> >On Aug 13, 2:09 pm, Jason Proctor <jason.android.li...@gmail.com>
> >wrote:
> >> why is there a 1mb file limit in this case?
> >> and is the restriction 1mb in the amount of stuff read, or in the
> >> size of the file?
> >> could you maybe open the file, skip a megabyte, then continue to read
> >> the second megabyte?
> >> >1048576 is the file limit
> >> >If you have bigger file split it
Jonathan wrote: > Right, you did say that, but as I mentioned I tested it and you were > absolutely right. Everything worked when I changed the extension > to .mp3.
Ah, sorry, I thought you were just paraphrasing -- I hadn't realized you tried it.
On the minus side, aapt does not appear to have a command-line switch to control this behavior (though I suspect Xav would be happy to see a patch).
On the plus side, remembering this correctly means I haven't killed off all my brain cells yet! Who-hoo! ;-)