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

序:一個文件夾下面有不少層的小文件,如何算出這個文件夾下面有多少文件?遞歸遍歷,簡單暴力,遞歸在通常狀況確實是比較方便的解決方案,可是當文件夾深度多深,遞歸的反覆調用會致使方法一直沒法釋放,形成jvm的棧溢出。那咱們該怎麼辦?html

原文和做者一塊兒討論:http://www.cnblogs.com/intsmaze/p/6031894.html
面試

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

  固然他跟我說這個問題的時候,它也沒有想到好的處理方案。它認爲這種狀況能夠參考網絡爬蟲的遞歸,爲了防止爬蟲在一個深度出不來,一般會設置每一次爬的深度,而後經過各類的限制條件來保證每個文件都被訪問到。數據結構

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

看,角落裏有咱們常常忽視的層序遍歷。spa

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

代碼思路:

咱們只須要使用一個list集合來存儲每個文件(夾),而後按次序讀取list集合的元素,並判斷若是是文件夾則把該文件夾下的全部文件(夾)追加到list集合後面,而後讀取list的下一個元素以此類推。htm

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]);
                 }
             }
         }
        
    }
}

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

固然有人會較真,當文件數量不少,就算這代碼能夠保證棧不溢出,可是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);
         }
    }
}

你們有更好的解決方案能夠一塊兒分享討論.

相關文章
相關標籤/搜索