2

I'm trying to read a bitmap from the Android /assets folder using the following code:

AssetFileDescriptor fd = getAssets().openFd("pic1.jpg")
Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor());

The exception I'm getting suggests that the file permissions are wrong:

java.io.IOException: read failed: EBADF (Bad file number)
    at libcore.io.IoBridge.read(IoBridge.java:432)
    at java.io.FileInputStream.read(FileInputStream.java:179)
    at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:168)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:309)
    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:587)
    at android.graphics.BitmapFactory.decodeFileDescriptor(BitmapFactory.java:670)
    at android.graphics.BitmapFactory.decodeFileDescriptor(BitmapFactory.java:688)

Attempting to read it from the input stream yields a similar exception:

AssetFileDescriptor fd = getAssets().openFd("pic1.jpg");
FileInputStream is = fd.createInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(is);

The exception:

java.io.IOException: lseek failed: EBADF (Bad file number)
Stack trace:
  at java.io.FileInputStream.skip(FileInputStream.java:197)
  at android.content.res.AssetFileDescriptor$AutoCloseInputStream.<init>(AssetFileDescriptor.java:173)
  at android.content.res.AssetFileDescriptor.createInputStream(AssetFileDescriptor.java:138)

Reading directly from the input stream gives yet another exception:

InputStream is = getAssets().open("pic1.jpg");
Bitmap bitmap = BitmapFactory.decodeStream(is);

The exception:

java.lang.NullPointerException: asset
  at android.content.res.AssetManager.seekAsset(Native Method)
  at android.content.res.AssetManager.access$600(AssetManager.java:35)
  at android.content.res.AssetManager$AssetInputStream.mark(AssetManager.java:567)
  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:572)
  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:643)

What's the correct way to read assets?

Paul Lammertsma
  • 37,593
  • 16
  • 136
  • 187
  • try `AssetFileDescriptor fd = getAssets().openFd("/pics/" + assets[i])` – Mohsin Naeem Oct 11 '12 at 18:17
  • That throws a `FileNotFoundException`, which is also what I receive when I provide a file name that doesn't exist. – Paul Lammertsma Oct 11 '12 at 18:23
  • try in this way http://stackoverflow.com/a/5903226/1436931 – Mohsin Naeem Oct 11 '12 at 18:29
  • Took a little debugging, but eventually determined that that results in the same exception; I'll update the question with the stack trace. – Paul Lammertsma Oct 11 '12 at 18:45
  • 1
    Oddly, the resource *does* appear for a moment before the application crashes. I hypothesize that the asset is trying to be read twice due to a bug elsewhere in my code. I'll simplify matters and get back here in a moment. – Paul Lammertsma Oct 11 '12 at 18:55
  • `BitmapFactory.decodeStream(getAssets().open("pic1.jpg"))` does appear to work, but crashes with the trace above when I attempt to load multiple assets in parallel from a background thread. Perhaps the method is not thread-safe? – Paul Lammertsma Oct 11 '12 at 19:02

1 Answers1

6

The problem was that I wasn't reading the asset from the main thread. In the application I was developing, two list items could concurrently loading the same, rather large, asset.

In short, if that file was still being read while another thread attempted to access it, an IOException would be thrown with "lseek failed: EBADF (Bad file number)".

Paul Lammertsma
  • 37,593
  • 16
  • 136
  • 187