<?xml version="1.0" encoding="gb2312" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">

<channel about="http://www.zhanglihai.com/b/rss2_3.xml">
<title>My Window,Your Bridge!</title> 
<link>http://www.zhanglihai.com/b/rss2_3.xml</link>
<description>关于技术,关于生活！</description>
<language>zh-cn</language>
<copyright>O-blog</copyright><item>
<title>备忘--JNI FileList的效率</title>
<link>http://www.zhanglihai.com/b/rss2_3.xml/archives/2008/01/24/opendir_jni_listFiles.html</link>
<pubDate>Thu, 24 Jan 2008 17:28:31 +0800</pubDate>
<guid>http://www.zhanglihai.com/b/rss2_3.xml/archives/2008/01/24/opendir_jni_listFiles.html</guid>
<description><![CDATA[ 我们知道java里面File对象既可以表示目录也可以表示文件。<br />如果我想得到某个目录下的所有文件那么只需要一行代码就可以了。<br />File files[] = new File(&quot;.&quot;).listFiles();<br /><br />如果目录下的文件过多，一般不会这样的。如果达到一定数目，那么这个执行这个方法时，可能导致内存溢出的异常。因为jdk是把该目录的所有文件都放到数组里面了，数组过大，栈空间不够了。<br /><br />我在linux上做的测试，疯狂创建了很多文件，就导致了这样的结果。<br /><br />此时如果我们用c来遍历该目录，c语言是移动指针的方式来做的，速度非常快。代码也非常简单。<br /><strong><br />但是这个过程中如果将文件删除此时性能急剧下降，相差2～3个数量级。因为在移除文件的时候数据库结构(Tree or Link)要不断的重新组合，所以性能急剧下降。</strong><br /><br />起初没有注意到这个问题，因为我是用jni调用的，调试时候发现listfile方法非常慢，因为我处理完文件对文件进行了删除。<br /><br />Java代码：<br /><div class="ubbcode"><br /> public class FileList{<br /><br />        public static native  String[] list(String path,int len);<br />        static native final void initialize();<br />        public static native final void destroy();<br />        static{<br />                 try{<br />                      System.loadLibrary(&quot;cfilelist&quot;);<br />                        initialize();<br />                    }catch(Exception ex){}<br />                }<br />}<br /></div><br /><br />FileList.h代码略<br />$&gt;javah    FileList<br />就可以产生<br /><br />dirlist.c代码<br /><div class="ubbcode"><br />  #include&lt;unistd.h&gt;<br />#include&lt;stdio.h&gt;<br />#include&lt;dirent.h&gt;<br />#include&lt;sys/stat.h&gt;<br />#include&lt;stdlib.h&gt;<br />#include&lt;string.h&gt;<br /><br />#include &quot;FileList.h&quot;<br />static jclass string_class;<br />void jni_log(const char *str){<br />       <br />}<br /><br />JNIEXPORT void JNICALL Java_FileList_initialize<br />  (JNIEnv *env, jclass jcls){<br /> jclass jstring_cls;<br /> jstring_cls=(*env)-&gt;FindClass(env,&quot;java/lang/String&quot;);<br /> if(jstring_cls)<br />        {<br />           string_class=(*env)-&gt;NewGlobalRef(env,jstring_cls);<br />        }<br />}<br /><br />JNIEXPORT void JNICALL Java_FileList_destroy<br />  (JNIEnv *env, jclass jcls){<br />    (*env)-&gt;DeleteGlobalRef(env, string_class);<br />}<br /><br />JNIEXPORT jobjectArray JNICALL Java_FileList_list<br />  (JNIEnv *env, jclass jcls, jstring jstrdir, jint jfcount){<br />        int f_count;<br />        jobjectArray jresult;<br />        DIR *pDir;<br />        char absPath[255];<br />        struct dirent *entry;<br />        struct stat statbuf;<br />        char *p_ch;<br />        const char *dir;<br />        if(string_class==NULL){<br />            jni_log(&quot;string_class==NULL&quot;);<br />           return NULL;<br />        }<br />        dir=(*env)-&gt;GetStringUTFChars(env,jstrdir,0);<br />        if(dir==NULL)<br />        {<br />                jni_log(&quot;dir==NULL&quot;);<br />            return NULL;<br />        }<br />        jresult=(*env)-&gt;NewObjectArray(env,(jsize)jfcount,string_class,NULL);<br />        if(jresult==NULL){<br />          jni_log(&quot;jresult==null&quot;);<br />          return NULL;<br />        }<br />        f_count=0;<br />         if((pDir = opendir(dir)) == NULL){<br />                 jni_log(&quot;open dir = null&quot;);<br />                   jni_log(dir);<br />                  return NULL;<br />          }<br />                chdir(dir);<br />                while((entry = readdir(pDir)) != NULL){<br />                        lstat(entry-&gt;d_name,&amp;statbuf);<br />                        if(S_ISDIR(statbuf.st_mode)) continue;                    //if(strcmp(entry-&gt;d_name,&quot;.&quot;)==0||strcmp(entry-&gt;d_name,&quot;..&quot;)==0)continue;<br />                        strcpy(absPath,dir);<br />                        strcat(absPath,&quot;/&quot;);<br />                        strcat(absPath,entry-&gt;d_name);<br />                         jstring jfilestr=(*env)-&gt;NewStringUTF(env,absPath);<br />                     (*env)-&gt;SetObjectArrayElement(env,jresult,(jsize)f_count,jfilestr);<br />                        f_count++;<br />                        if(f_count&gt;=jfcount)break;<br />                }<br />                closedir(pDir);<br />                chdir(&quot;..&quot;);<br />        (*env)-&gt;ReleaseStringUTFChars(env,jstrdir,dir);<br />   return jresult;<br />}<br /><br /></div>]]></description>
</item></channel>
</rss>