RandomAccessFile in Android raw resource file

It's simply not possible to seek forward and back in an input stream without buffering everything in between into memory. That can be extremely costly, and isn't a scalable solution for reading a (binary) file of some arbitrary size.

You're right: ideally, one would use a RandomAccessFile, but reading from the resources provides an input stream instead. The suggestion mentioned in the comments above is to use the input stream to write the file to the SD card, and randomly access the file from there. You could consider writing the file to a temporary directory, reading it, and deleting it after use:

String file = "your_binary_file.bin";
AssetFileDescriptor afd = null;
FileInputStream fis = null;
File tmpFile = null;
RandomAccessFile raf = null;
try {
    afd = context.getAssets().openFd(file);
    long len = afd.getLength();
    fis = afd.createInputStream();
    // We'll create a file in the application's cache directory
    File dir = context.getCacheDir();
    dir.mkdirs();
    tmpFile = new File(dir, file);
    if (tmpFile.exists()) {
        // Delete the temporary file if it already exists
        tmpFile.delete();
    }
    FileOutputStream fos = null;
    try {
        // Write the asset file to the temporary location
        fos = new FileOutputStream(tmpFile);
        byte[] buffer = new byte[1024];
        int bufferLen;
        while ((bufferLen = fis.read(buffer)) != -1) {
            fos.write(buffer, 0, bufferLen);
        }
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {}
        }
    }
    // Read the newly created file
    raf = new RandomAccessFile(tmpFile, "r");
    // Read your file here
} catch (IOException e) {
    Log.e(TAG, "Failed reading asset", e);
} finally {
    if (raf != null) {
        try {
            raf.close();
        } catch (IOException e) {}
    }
    if (fis != null) {
        try {
            fis.close();
        } catch (IOException e) {}
    }
    if (afd != null) {
        try {
            afd.close();
        } catch (IOException e) {}
    }
    // Clean up
    if (tmpFile != null) {
        tmpFile.delete();
    }
}

Tags:

Android