如何遍歷文件夾下上億文件而不棧溢出


序:一個文件夾下面有很多層的小文件,如何算出這個文件夾下面有多少文件?遞歸遍歷,簡單暴力,遞歸在一般情況確實是比較方便的解決方案,但是當文件夾深度多深,遞歸的反復調用會導致方法一直無法釋放,造成jvm的棧溢出。那我們該怎么辦?

原文和作者一起討論:http://www.cnblogs.com/intsmaze/p/6031894.html

  說實話這個問題我以前也沒有遇到過,我是聽一位我很敬佩的IT前輩講的他曾經的面試經歷。他說他當時比較緊張就想到了遞歸,沒有想到其他的方案。

  當然他跟我說這個問題的時候,它也沒有想到好的處理方案。它認為這種情況可以參考網絡爬蟲的遞歸,為了防止爬蟲在一個深度出不來,通常會設置每一次爬的深度,然后通過各種的限制條件來保證每一個文件都被訪問到。

  當時我靈光一閃,因為當時我在溫故數據結構的知識,我說這個文件夾的層次看着好呀嘛好眼熟,不就相當於一個樹的結構,那我們學數據結構的時候是如何遍歷節點的。有左遞歸,中遞歸,右遞歸,當然這就是上面的遞歸方法,不是我們要找的解決方案,那么該怎么辦?

看,角落里有我們經常忽視的層序遍歷。

  層序遍歷:層序遍歷就是從所在樹的根節點出發,首先訪問第一層的樹根節點,然后從左到右訪問第2層上的節點,接着是第三層的節點,以此類推,自上而下,自左至右逐層訪問樹的結點的過程就是層序遍歷。

代碼思路:

我們只需要使用一個list集合來存儲每一個文件(夾),然后按次序讀取list集合的元素,並判斷如果是文件夾則把該文件夾下的所有文件(夾)追加到list集合后面,然后讀取list的下一個元素以此類推。

public class demo {
    public static void main(String[] args) {
        List<File> list=new ArrayList<File>();
        File file = new File("C:/intsmaze");
        list.add(file);
         for(int i=0;i<list.size();i++)
         {
             if(list.get(i).isDirectory())
             {
                 File[] tempList = list.get(i).listFiles();
                 for(int j=0;j<tempList.length;j++)
                 {
                     list.add(tempList[j]);
                 }
             }
         }
        
    }
}

都是有經驗的開發人員,上面的代碼就沒有必要進行注釋了。

當然有人會較真,當文件數量很多,就算這代碼可以保證棧不溢出,但是list集合數量上去了,堆也會爆的。

當然,這是一種情況,其實也很簡單,每從集合讀取一個元素,就把該元素從集合溢出,存入硬盤中即可,然后循環里面的判斷條件中不對i進行遞增即可。

public class demo {
    public static void main(String[] args) {
        List<File> list=new ArrayList<File>();
        File file = new File("C:/intsmaze");
        list.add(file);
         for(int i=0;i<list.size();)
         {
             if(list.get(i).isDirectory())
             {
                 File[] tempList = list.get(i).listFiles();
                 for(int j=0;j<tempList.length;j++)
                 {
                     list.add(tempList[j]);
                 }
             }
             list.remove(i);
         }
    }
}

大家有更好的解決方案可以一起分享討論.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM