My Window,Your Bridge!

关于技术,关于生活!


备忘--JNI FileList的效率



我们知道java里面File对象既可以表示目录也可以表示文件。
如果我想得到某个目录下的所有文件那么只需要一行代码就可以了。
File files[] = new File(".").listFiles();

如果目录下的文件过多,一般不会这样的。如果达到一定数目,那么这个执行这个方法时,可能导致内存溢出的异常。因为jdk是把该目录的所有文件都放到数组里面了,数组过大,栈空间不够了。

我在linux上做的测试,疯狂创建了很多文件,就导致了这样的结果。

此时如果我们用c来遍历该目录,c语言是移动指针的方式来做的,速度非常快。代码也非常简单。

但是这个过程中如果将文件删除此时性能急剧下降,相差2~3个数量级。因为在移除文件的时候数据库结构(Tree or Link)要不断的重新组合,所以性能急剧下降。


起初没有注意到这个问题,因为我是用jni调用的,调试时候发现listfile方法非常慢,因为我处理完文件对文件进行了删除。

Java代码:

 public class FileList{

        public static native  String[] list(String path,int len);
        static native final void initialize();
        public static native final void destroy();
        static{
                 try{
                      System.loadLibrary("cfilelist");
                        initialize();
                    }catch(Exception ex){}
                }
}


FileList.h代码略
$>javah    FileList
就可以产生

dirlist.c代码

  #include<unistd.h>
#include<stdio.h>
#include<dirent.h>
#include<sys/stat.h>
#include<stdlib.h>
#include<string.h>

#include "FileList.h"
static jclass string_class;
void jni_log(const char *str){
       
}

JNIEXPORT void JNICALL Java_FileList_initialize
  (JNIEnv *env, jclass jcls){
 jclass jstring_cls;
 jstring_cls=(*env)->FindClass(env,"java/lang/String");
 if(jstring_cls)
        {
           string_class=(*env)->NewGlobalRef(env,jstring_cls);
        }
}

JNIEXPORT void JNICALL Java_FileList_destroy
  (JNIEnv *env, jclass jcls){
    (*env)->DeleteGlobalRef(env, string_class);
}

JNIEXPORT jobjectArray JNICALL Java_FileList_list
  (JNIEnv *env, jclass jcls, jstring jstrdir, jint jfcount){
        int f_count;
        jobjectArray jresult;
        DIR *pDir;
        char absPath[255];
        struct dirent *entry;
        struct stat statbuf;
        char *p_ch;
        const char *dir;
        if(string_class==NULL){
            jni_log("string_class==NULL");
           return NULL;
        }
        dir=(*env)->GetStringUTFChars(env,jstrdir,0);
        if(dir==NULL)
        {
                jni_log("dir==NULL");
            return NULL;
        }
        jresult=(*env)->NewObjectArray(env,(jsize)jfcount,string_class,NULL);
        if(jresult==NULL){
          jni_log("jresult==null");
          return NULL;
        }
        f_count=0;
         if((pDir = opendir(dir)) == NULL){
                 jni_log("open dir = null");
                   jni_log(dir);
                  return NULL;
          }
                chdir(dir);
                while((entry = readdir(pDir)) != NULL){
                        lstat(entry->d_name,&statbuf);
                        if(S_ISDIR(statbuf.st_mode)) continue;                    //if(strcmp(entry->d_name,".")==0||strcmp(entry->d_name,"..")==0)continue;
                        strcpy(absPath,dir);
                        strcat(absPath,"/");
                        strcat(absPath,entry->d_name);
                         jstring jfilestr=(*env)->NewStringUTF(env,absPath);
                     (*env)->SetObjectArrayElement(env,jresult,(jsize)f_count,jfilestr);
                        f_count++;
                        if(f_count>=jfcount)break;
                }
                closedir(pDir);
                chdir("..");
        (*env)->ReleaseStringUTFChars(env,jstrdir,dir);
   return jresult;
}


该日志的引用地址:

发表评论:



日历

网站目录

搜索

Powered By O-Blog | Template Modified By FengSe

Copyright 2003-2007 ZhangLiHai.Com.All Rights Reserved.