Skip to content Skip to sidebar Skip to footer

Randomaccessfile In Android Raw Resource File

I tried to create a RandomAccessFile object from a raw resource file in android resource directory without success. I'm only able to get a inputstream object from raw resource fil

Solution 1:

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:

Stringfile="your_binary_file.bin";
AssetFileDescriptorafd=null;
FileInputStreamfis=null;
FiletmpFile=null;
RandomAccessFileraf=null;
try {
    afd = context.getAssets().openFd(file);
    longlen= afd.getLength();
    fis = afd.createInputStream();
    // We'll create a file in the application's cache directoryFiledir= context.getCacheDir();
    dir.mkdirs();
    tmpFile = newFile(dir, file);
    if (tmpFile.exists()) {
        // Delete the temporary file if it already exists
        tmpFile.delete();
    }
    FileOutputStreamfos=null;
    try {
        // Write the asset file to the temporary location
        fos = newFileOutputStream(tmpFile);
        byte[] buffer = newbyte[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 = newRandomAccessFile(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 upif (tmpFile != null) {
        tmpFile.delete();
    }
}

Solution 2:

Why not get a new AssetFileDescriptor each time you need a seek? It seems not to be a cpu cycles intensive task (or is it?)

//seek to your first start positionInputStreamins= getAssets().openFd("your_file_name").createInputStream();
isChunk.skip(start);
//read some bytes
ins.read(toThisBuffer, 0, length);

//later on//seek to a different position, need to openFd again! //because createInputStream can be called on asset file descriptor only once.//This resets the new stream to file offset 0, //so need to seek (skip()) to a new position relative to file beginning.

ins = getAssets().openFd("your_file_name").createInputStream();
ins.skip(start2);

//read some bytes
ins.read(toThatBuffer, 0, length);

I've used this method in my app that needs random access to a 20Mb resource file hundreds of times per second.

Post a Comment for "Randomaccessfile In Android Raw Resource File"