Discrepancies between Android's various ways to access assets via AssetManager
<p>I'm a beginner Android programmer who has run into a weird issue with using the various methods for reading assets from the AssetManager.  </p>

<p>I've attached sample code below that exhibits this issue.  It reads a simple text file asset ("hello.txt") that contains "hello".  I read it in as raw bytes and print out the hexadecimal values of the characters (68 65 6c 6c 6f).</p>

<p>The ways I've tried are (in order in the code):</p>

<ul>
<li>open AssetFileDescriptor (AFD), create InputStream: only reads in the first three bytes (68 65 6c ffffffff ffffffff)</li>
<li>open AFD, get underlying file descriptor, create FileInputStream: completely wrong data (50 4b 3 4 a)</li>
<li>open InputStream directly: correct (68 65 6c 6c 6f)</li>
</ul>

<p>I've also repeated the same three methods, this time reading into a byte array first, which (surprisingly!) changes the first result but otherwise yields the same results (repeated here for convenience):</p>

<ul>
<li>open AFD, create InputStream, read into byte array first: correct (68 65 6c 6c 6f)</li>
<li>open AFD, get underlying file descriptor, create FileInputStream, read into byte array first: completely wrong data (50 4b 3 4 a)</li>
<li>open InputStream directly, read into byte array first: correct (68 65 6c 6c 6f)</li>
</ul>

<p>Note that, with the exception of the very first case (when only three bytes are read in), the other cases read exactly 6 bytes (including the newline at the end) and will subsequently return -1 afterwards as expected.  This includes those cases where wrong data is read in.</p>

<p>Has anyone run into this before?  Is this a bug, or did I do something wrong?</p>

<p>Thanks!</p>

<pre><code>public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    AssetManager am = getAssets();
    StringBuilder sb = new StringBuilder();

    try {
        AssetFileDescriptor afd = am.openFd("hello.txt"); 
        InputStream instream = afd.createInputStream();
        sb.append(String.format("afd.createInputStream(): %x %x %x %x %x\n", instream.read(), instream.read(), instream.read(), instream.read(), instream.read()));
        instream.close();
        afd.close();
    }
    catch (IOException e) {
        throw new RuntimeException(e);
    }

    try {
        AssetFileDescriptor afd = am.openFd("hello.txt");
        InputStream instream = new FileInputStream(afd.getFileDescriptor());
        sb.append(String.format("new FileInputStream(afd): %x %x %x %x %x\n", instream.read(), instream.read(), instream.read(), instream.read(), instream.read()));
        instream.close();
        afd.close();
    }
    catch (IOException e) {
        throw new RuntimeException(e);
    }

    try {
        InputStream instream = am.open("hello.txt");
        sb.append(String.format("am.open(): %x %x %x %x %x\n", instream.read(), instream.read(), instream.read(), instream.read(), instream.read()));
        instream.close();
    }
    catch (IOException e) {
        throw new RuntimeException(e);
    }

    try {
        AssetFileDescriptor afd = am.openFd("hello.txt");
        InputStream instream = afd.createInputStream();
        byte[] b = new byte[instream.available()];
        instream.read(b);
        sb.append(String.format("afd.createInputStream() -&gt; byte[]: %x %x %x %x %x\n", b[0], b[1], b[2], b[3], b[4]));
        instream.close();
        afd.close();
    }
    catch (IOException e) {
        throw new RuntimeException(e);
    }

    try {
        AssetFileDescriptor afd = am.openFd("hello.txt");
        InputStream instream = new FileInputStream(afd.getFileDescriptor());
        byte[] b = new byte[(int) afd.getLength()];
        instream.read(b);
        sb.append(String.format("new FileInputStream(afd) -&gt; byte[]: %x %x %x %x %x\n", b[0], b[1], b[2], b[3], b[4]));
        instream.close();
        afd.close();
    }
    catch (IOException e) {
        throw new RuntimeException(e);
    }

    try {
        InputStream instream = am.open("hello.txt");
        byte[] b = new byte[instream.available()];
        instream.read(b);
        sb.append(String.format("am.open() -&gt; byte[]: %x %x %x %x %x\n", b[0], b[1], b[2], b[3], b[4]));
        instream.close();
    }
    catch (IOException e) {
        throw new RuntimeException(e);
    }

    // print result
    TextView textview = (TextView) findViewById(R.id.textview);
    textview.setText(sb.toString());
    Log.d("blah", sb.toString());
}
</code></pre>
