posts - 262,  comments - 221,  trackbacks - 0
Apache commons IO包中提供了一个可以遍历目录下资源的DirectoryWalker,还有很多的IOFileFilter用于过滤文件目录。下面的例子分别演示了这个功能。

这两个搜索类都是以内部类的方式嵌入客户端的,客户端接收客户的参数,然后通过一个后台线程来进行搜索,等待子线程完成搜索后(join方法),再打印搜索结果。

注意这个过程是可以被cancel的。cancel主要有2种情况。外部cancel:外部线程通过调用内部类的cancel()方法。内部cancel:在handleDirectory、handleFile中主动抛出CancelException。

walk方法在每次执行前、后都会检查当前是否有cancel指令发出(checkIfCancelled ---> handleIsCancelled),如果有那么默认立刻抛出CancelException,然后调用handleCancelled方法。

这里搜索实现类被实现为一个内部类,目的是不想暴露内部的搜索过程逻辑,只对外暴露客户端接口。其次内部采用线程实现,方便充当客户端的外部类可以在必要时cancel这个内部线程操作,而且当搜索过程漫长时不会造成界面假死(GUI界面)。

在搜索过程中,我们可以对搜索到文件、资源进行处理,例如:删除,重命名,移动等。最常见的一个应用就是批量删除搜索到的文件。例如.svn目录或日志文件

   /**
     * Main recursive method to examine the directory hierarchy.
     *
     * 
@param directory  the directory to examine, not null
     * 
@param depth  the directory level (starting directory = 0)
     * 
@param results  the collection of result objects, may be updated
     * 
@throws IOException if an I/O Error occurs
     
*/

    
private void walk(File directory, int depth, Collection results) throws IOException {
        checkIfCancelled(directory, depth, results);
        
if (handleDirectory(directory, depth, results)) {
            handleDirectoryStart(directory, depth, results);
            
int childDepth = depth + 1;
            
if (depthLimit < 0 || childDepth <= depthLimit) {
                checkIfCancelled(directory, depth, results);
                File[] childFiles 
= (filter == null ? directory.listFiles() : directory.listFiles(filter));
                
if (childFiles == null{
                    handleRestricted(directory, childDepth, results);
                }
 else {
                    
for (int i = 0; i < childFiles.length; i++{
                        File childFile 
= childFiles[i];
                        
if (childFile.isDirectory()) {
                            walk(childFile, childDepth, results);
                        }
 else {
                            checkIfCancelled(childFile, childDepth, results);
                            handleFile(childFile, childDepth, results);
                            checkIfCancelled(childFile, childDepth, results);
                        }

                    }

                }

            }

            handleDirectoryEnd(directory, depth, results);
        }

        checkIfCancelled(directory, depth, results);
    }


【一】从根目录开始,查询(指定目录下)指定的文件

  1package example.io;
  2
  3import java.io.File;
  4import java.io.IOException;
  5import java.util.ArrayList;
  6import java.util.Collection;
  7import java.util.List;
  8
  9import org.apache.commons.io.DirectoryWalker;
 10import org.apache.commons.io.FilenameUtils;
 11import org.apache.commons.io.filefilter.FileFilterUtils;
 12
 13/**
 14 * The Class FileSearcher.
 15 */

 16public class FileSearcher {
 17
 18    /**
 19     * The main method.
 20     * 
 21     * @param args the arguments
 22     */

 23    public static void main(String[] args) {
 24        String baseDir = null;
 25        String targetDir = null;
 26        String targetFile = null;
 27
 28        if (args == null || args.length == 0{
 29            System.err.println("Error: Missing start directory name");
 30            System.exit(-1);
 31        }

 32        if (args == null || args.length == 1{
 33            System.err.println("Error: Missing target file name");
 34            System.exit(-1);
 35        }

 36
 37        FileSearcher searcher = new FileSearcher();
 38        // Only base directory and file name are given
 39        if (args != null && args.length == 2{
 40            baseDir = args[0];
 41            targetFile = args[1];
 42            searcher.search(baseDir, targetFile);
 43        }

 44        // Both base and parent directories name and file name are given
 45        if (args != null && args.length >= 3{
 46            baseDir = args[0];
 47            targetDir = args[1];
 48            targetFile = args[2];
 49            searcher.search(baseDir, targetDir, targetFile);
 50        }

 51    }

 52
 53    /**
 54     * Search by file name
 55     * 
 56     * @param baseDir the base dir
 57     * @param targetFile the target file
 58     */

 59    public void search(String baseDir, String targetFile) {
 60        search(baseDir, null, targetFile);
 61    }

 62
 63    /**
 64     * Search by file name and parent directory name
 65     * 
 66     * @param baseDir the base dir
 67     * @param targetDir the target dir
 68     * @param targetFile the target file
 69     */

 70    public void search(String baseDir, String targetDir, String targetFile) {
 71        // File existence check
 72        if ((baseDir == null || baseDir.trim().length() == 0)
 73                || (targetFile == null || (targetFile.trim().length() == 0))) {
 74            System.err.println("Error: Missing base directory or file name");
 75            System.exit(-1);
 76        }

 77
 78        File startDirectory = new File(baseDir);
 79        if (!startDirectory.exists()) {
 80            System.err.println("Error: Couldn't find path by given parameter");
 81            System.exit(-1);
 82        }

 83        // Create a new thread and start to search
 84        SearchFileWalker walker = new SearchFileWalker(startDirectory,
 85                targetDir, targetFile);
 86        Thread searchThread = new Thread(walker);
 87        searchThread.start();
 88        System.out.println("Start to search ");
 89
 90        try {
 91            searchThread.join(); // child thread join to main thread
 92        }
 catch (InterruptedException e) {
 93            e.printStackTrace();
 94        }

 95        walker.displaySearchResult();
 96    }

 97
 98    class SearchFileWalker extends DirectoryWalker implements Runnable {
 99
100        private volatile boolean cancelled = false;
101
102        private boolean matchByFileNameOnly = true;
103
104        private File baseDir;
105
106        private String targetDirName;
107
108        private String targetFileName;
109
110        private List<File> finalResult = new ArrayList<File>();
111
112        /**
113         * Instantiates a new search directory walker.
114         * 
115         * @param startDir the start dir
116         * @param targetFile the target file
117         */

118        public SearchFileWalker(File startDir, String targetFile) {
119            this(startDir, null, targetFile);
120        }

121
122        /**
123         * Instantiates a new search directory walker.
124         * 
125         * @param startDir the start dir
126         * @param targetDir the target dir
127         * @param targetFile the target file
128         */

129        public SearchFileWalker(File startDir, String targetDir,
130                String targetFile) {
131            super();
132            baseDir = startDir;
133            targetDirName = targetDir;
134            targetFileName = targetFile;
135            matchByFileNameOnly = (targetDirName == null? true : false;
136        }

137
138        /*
139         * (non-Javadoc)
140         * 
141         * @see java.lang.Runnable#run()
142         */

143        public void run() {
144            search();
145        }

146
147        /**
148         * Search.
149         */

150        public void search() {
151            List<File> searchResult = new ArrayList<File>();
152            try {
153                walk(baseDir, searchResult);
154            }
 catch (IOException e) {
155                e.printStackTrace();
156            }

157            finalResult = searchResult;
158        }

159
160        /**
161         * Gets the result.
162         * 
163         * @return the result
164         */

165        public List<File> getResult() {
166            return finalResult;
167        }

168
169        /**
170         * Display search result.
171         */

172        public void displaySearchResult() {
173            File f = null;
174            System.out.println("\n=======================================");
175            for (