我們?cè)陂_發(fā)中,經(jīng)常需要遍歷一個(gè)目錄下的所有文件,常用的辦法就是使用一個(gè)函數(shù)遞歸遍歷是常用的辦法。例如:
          public static void iterateFile(File file) {
              
          if (file.isDirectory()) {
                  
          if (file.getName().startsWith(".")) return;

                  
          for (File item : file.listFiles()) {
                      iterateFile(item);
                  }
                  
          return;
              }

              
          // do something 
          }


          但是遞歸函數(shù)的缺點(diǎn)就是擴(kuò)展不方便,當(dāng)然你對(duì)這個(gè)函數(shù)加入一個(gè)參數(shù)FileHandler,這樣擴(kuò)展性稍好一些,但是仍然不夠好,比如說,不能根據(jù)遍歷的 需要中途停止遍歷,加入Filter等等。我實(shí)現(xiàn)了一個(gè)FileIterator,使得遍歷一個(gè)目錄下的文件如何遍歷一個(gè)集合中的元素一般操作。

          廢話少說,代碼如下:
          package net.wenshao;

          import java.io.File;
          import java.util.Iterator;
          import java.util.NoSuchElementException;

          public class FileIterator implements Iterator<File> {
              
          private static class State {
                  
          final State parent;
                  
          final File[] files;

                  
          int index = 0;

                  
          public State(State parent, File dir) {
                      
          this.parent = parent;
                      files 
          = dir.listFiles();
                  }
              }

              
          private File current;

              
          private State state;

              
          public FileIterator(File file) {
                  
          if (file.isDirectory()) {
                      state 
          = new State(null, file);
                      nextInternal();
                  } 
          else {
                      
          this.current = file;
                      state 
          = null;
                  }
              }

              @Override
              
          public boolean hasNext() {
                  
          return current != null;
              }

              @Override
              
          public File next() {
                  File rtValue 
          = current;

                  
          if (rtValue == nullthrow new NoSuchElementException();

                  nextInternal();

                  
          return rtValue;
              }

              
          private void nextInternal() {
                  current 
          = null;

                  
          if (this.state == nullreturn;

                  
          for (;;) {
                      
          if (state.index >= state.files.length) {
                          state 
          = state.parent;
                          
          if (state == null) return;
                          state.index
          ++;
                          
          continue;
                      }

                      File file 
          = state.files[state.index];
                      
                      
          // 可以在此處加入Filters處理代碼
                      
                      
          if (file.isDirectory()) {
                          state 
          = new State(state, file);
                          
          continue;
                      }

                      current 
          = file;
                      state.index
          ++;
                      
          break;
                  }
              }

              @Override
              
          public void remove() {
                  
          throw new UnsupportedOperationException();
              }
          }

          使用FileIterator的例子:
          File dir = new File("/home/wenshao/workspace");

          Iterator
          <File> iter = new FileIterator(dir);
          while (iter.hasNext()) {
              File file 
          = iter.next();
              System.out.println(file.getPath());
          }

          posted on 2008-06-05 07:56 溫少的日志 閱讀(1902) 評(píng)論(2)  編輯  收藏
          Comments
          • # re: 一個(gè)FileIterator的實(shí)現(xiàn)
            kingslee
            Posted @ 2008-08-27 15:15
            State對(duì)象的聲明,有些“為了對(duì)象而對(duì)象”的味道??梢灾苯佑肁rrayList或者Stack作為存儲(chǔ)結(jié)構(gòu),語義更加簡(jiǎn)明。

            遍歷大的文件目錄時(shí),有時(shí)候深度優(yōu)先好些,有時(shí)候廣度優(yōu)先好些。上述代碼中如果推算不錯(cuò)的話,應(yīng)當(dāng)是深度優(yōu)先。  回復(fù)  更多評(píng)論   
          • # re: 一個(gè)FileIterator的實(shí)現(xiàn)
            溫少的日志
            Posted @ 2008-08-30 16:12
            回kingslee
            1、State有三個(gè)field,parent、index和files,不聲明一個(gè)對(duì)象,使用ArrayList不好,聲明一個(gè)對(duì)象語義更明確。
            2、這是深度優(yōu)先的,廣度優(yōu)先的實(shí)現(xiàn)方式會(huì)有所不同。  回復(fù)  更多評(píng)論   

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
           
          主站蜘蛛池模板: 克东县| 呼图壁县| 迁西县| 哈巴河县| 涞水县| 拉萨市| 林州市| 山阴县| 博白县| 观塘区| 江都市| 荥阳市| 青川县| 江津市| 陇川县| 拜城县| 南阳市| 高唐县| 南昌市| 昆山市| 四平市| 喀喇| 定结县| 东方市| 南靖县| 通辽市| 区。| 太白县| 仪征市| 青铜峡市| 大竹县| 乡宁县| 天祝| 邹城市| 阜康市| 濉溪县| 织金县| 门源| 凌海市| 七台河市| 驻马店市|