android -- MemoryFile 内存文件(IO性能优化)

前些天还自已写了一个内存文件用于http数据交互使用,没想到今天翻代码,尽然找到类似的现有实现,真是汗! 呵呵,那么就在这简要介绍一下吧!


应用场合:

1、对于I/O需要频繁操作的,主要是和外部存储相关的I/O操作,MemoryFile通过将 NAND或SD卡上的文件,分段映射到内存中进行修改处理,这样就用高速的RAM代替了ROM或SD卡,性能自然提高不少,对于Android手机而言同时还减少了电量消耗。

2、对于java与jni大数据交互的话使用起来还是相当方便,只要将数据格式定义好即可。


类  MemoryFile.java  

路径:frameworks\base\core\java\android\os


JNI 实现 frameworks\base\core\jni\android_os_MemoryFile.cpp


用法:MemoryFileTest.java 这个文件中有例子, 我这里列一下基本的用法函数

    @SmallTest
    public void testFileDescriptor() throws Exception {
        MemoryFile file = new MemoryFile("MemoryFileTest", 1000000);
        MemoryFile ref = new MemoryFile(file.getFileDescriptor(), file.length(), "r");
        byte[] buffer;

        // write to original, read from reference
        file.writeBytes(testString, 0, 2000, testString.length);
        buffer = new byte[testString.length];
        ref.readBytes(buffer, 2000, 0, testString.length);
        compareBuffers(testString, buffer, testString.length);

        file.close();
        ref.close();  // Doesn't actually do anything, since the file descriptor is not dup(2):ed
    }

比较数据函数:

    private void compareBuffers(byte[] buffer1, byte[] buffer2, int length) throws Exception {
        for (int i = 0; i < length; i++) {
            if (buffer1[i] != buffer2[i]) {
                throw new Exception("readBytes did not read back what writeBytes wrote");
            }
        }
    }

ok, 使用非常简单


下面来分析下其实现的主要原素,大内存数据读写肯定离不开内存映射,这里必须使用到了 mmap / munmap 

static jint android_os_MemoryFile_mmap(JNIEnv* env, jobject clazz, jobject fileDescriptor,
        jint length, jint prot)
{
    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
    jint result = (jint)mmap(NULL, length, prot, MAP_SHARED, fd, 0);
    if (!result)
        jniThrowException(env, "java/io/IOException", "mmap failed");
    return result;
}

static void android_os_MemoryFile_munmap(JNIEnv* env, jobject clazz, jint addr, jint length)
{
    int result = munmap((void *)addr, length);
    if (result < 0)
        jniThrowException(env, "java/io/IOException", "munmap failed");
}

分配内存使用匿名内存实现:

static jobject android_os_MemoryFile_open(JNIEnv* env, jobject clazz, jstring name, jint length)
{
    const char* namestr = (name ? env->GetStringUTFChars(name, NULL) : NULL);

    int result = ashmem_create_region(namestr, length);

数据读和写实现:

static jint android_os_MemoryFile_read(JNIEnv* env, jobject clazz,
        jobject fileDescriptor, jint address, jbyteArray buffer, jint srcOffset, jint destOffset,
        jint count, jboolean unpinned)
{
     int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

     ...
     env->SetByteArrayRegion(buffer, destOffset, count, (const jbyte *)address + srcOffset);

     return count;
}


static jint android_os_MemoryFile_write(JNIEnv* env, jobject clazz,
        jobject fileDescriptor, jint address, jbyteArray buffer, jint srcOffset, jint destOffset,
        jint count, jboolean unpinned)
{

    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
      ...
   env->GetByteArrayRegion(buffer, srcOffset, count, (jbyte *)address + destOffset);
   return count;
}
 



  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值