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 (int i = 0; i < finalResult.size(); i++{
176                f = (File) finalResult.get(i);
177                System.out.println("  File found: " + f.getAbsolutePath());
178            }

179            System.out.println("=======================================\n");
180        }

181
182        /*
183         * (non-Javadoc)
184         * 
185         * @see org.apache.commons.io.DirectoryWalker#handleDirectory(java.io.File,
186         *      int, java.util.Collection)
187         */

188        protected boolean handleDirectory(File directory, int depth,
189                Collection results) throws IOException {
190
191            System.out.println("\nSearching under directory: "
192                    + directory.getAbsolutePath());
193            if (matchByFileNameOnly) {
194                return true// Match by file name only
195            }
 else if (FilenameUtils.equalsNormalizedOnSystem(targetDirName,
196                    directory.getName())) {
197                return true// Parent directory name matched
198            }
 else if (directory.list(FileFilterUtils.directoryFileFilter()).length > 0{
199                return true// Has child directory
200            }
 else {
201                return false// Empty directory or file name doesn't match
202            }

203        }

204
205        /*
206         * (non-Javadoc)
207         * 
208         * @see org.apache.commons.io.DirectoryWalker#handleFile(java.io.File,
209         *      int, java.util.Collection)
210         */

211        protected void handleFile(File file, int depth, Collection results)
212                throws IOException {
213
214            // Matches by file name only
215            if (targetFileName.equals(file.getName()) && matchByFileNameOnly) {
216                results.add(file);
217            }

218            // Matches by directory name and file name
219            if (FilenameUtils.equalsNormalizedOnSystem(targetFileName, file
220                    .getName())
221                    && (!matchByFileNameOnly)) {
222                String fullPath = FilenameUtils.getFullPathNoEndSeparator(file
223                        .getAbsolutePath());
224                String fileParentDir = fullPath.substring(FilenameUtils
225                        .indexOfLastSeparator(fullPath) + 1);
226                if (FilenameUtils.equalsOnSystem(targetDirName, fileParentDir)) {
227                    results.add(file);
228                }

229            }

230        }

231
232        /**
233         * Cancel.
234         */

235        public void cancel() {
236            cancelled = true;
237        }

238
239        /*
240         * (non-Javadoc)
241         * 
242         * @see org.apache.commons.io.DirectoryWalker#handleIsCancelled(java.io.File,
243         *      int, java.util.Collection)
244         */

245        protected boolean handleIsCancelled(File file, int depth,
246                Collection results) {
247            return cancelled;
248        }

249
250        /*
251         * (non-Javadoc)
252         * 
253         * @see org.apache.commons.io.DirectoryWalker#handleCancelled(java.io.File,
254         *      java.util.Collection,
255         *      org.apache.commons.io.DirectoryWalker.CancelException)
256         */

257        protected void handleCancelled(File startDirectory, Collection results,
258                CancelException cancel) {
259            if (cancelled) {
260                cancel();
261            }

262            System.out.println("\nCancelled by external or interal thread");
263            finalResult = (List<File>) results;
264        }

265    }

266
267}

【二】从根目录开始,查找指定的目录

package example.io;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.io.DirectoryWalker;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;

/**
 * The Class DirectorySearcher.
 
*/

public class DirectorySearcher {

    
/**
     * The main method.
     * 
     * 
@param args the arguments
     
*/

    
public static void main(String[] args) {
        String baseDir 
= null;
        String targetDir 
= null;

        
if (args == null || args.length == 0{
            System.err.println(
"Error: Missing start directory name");
            System.exit(
-1);
        }

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


        baseDir 
= args[0];
        targetDir 
= args[1];
        DirectorySearcher searcher 
= new DirectorySearcher();
        searcher.search(baseDir, targetDir);
    }


    
/**
     * Search by directory name
     * 
     * 
@param baseDir the base dir
     * 
@param targetDir the target dir
     
*/

    
public void search(String baseDir, String targetDir) {
        
// File existence check
        if ((baseDir == null || baseDir.trim().length() == 0)
                
|| (targetDir == null || (targetDir.trim().length() == 0))) {
            System.err.println(
"Error: Missing base or target directory name");
            System.exit(
-1);
        }


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

        
// Create a new thread and start to search
        SearchDirectoryWalker walker = new SearchDirectoryWalker(
                startDirectory, targetDir);
        Thread searchThread 
= new Thread(walker);
        searchThread.start();
        System.out.println(
"Start to search ");

        
try {
            searchThread.join(); 
// child thread join to main thread
        }
 catch (InterruptedException e) {
            e.printStackTrace();
        }

        walker.displaySearchResult();
    }


    
/**
     * The Class SearchDirectoryWalker.
     
*/

    
class SearchDirectoryWalker extends DirectoryWalker implements Runnable {

        
private volatile boolean cancelled = false;

        
private File baseDir;

        
private String targetDirName;

        
private List<File> finalResult = new ArrayList<File>();

        
/**
         * Instantiates a new search directory walker.
         * 
         * 
@param startDir the start dir
         * 
@param targetDir the target dir
         
*/

        
public SearchDirectoryWalker(File startDir, String targetDir) {
            
super(FileFilterUtils.directoryFileFilter(), -1);
            baseDir 
= startDir;
            targetDirName 
= targetDir;
        }


        
/*
         * (non-Javadoc)
         * 
         * @see java.lang.Runnable#run()
         
*/

        
public void run() {
            search();
        }


        
/**
         * Search.
         
*/

        
public void search() {
            List
<File> searchResult = new ArrayList<File>();
            
try {
                walk(baseDir, searchResult);
            }
 catch (IOException e) {
                e.printStackTrace();
            }

            finalResult 
= searchResult;
        }


        
/**
         * Gets the result.
         * 
         * 
@return the result
         
*/

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


        
/**
         * Display search result.
         
*/

        
public void displaySearchResult() {
            File f 
= null;
            System.out.println(
"\n=======================================");
            
for (int i = 0; i < finalResult.size(); i++{
                f 
= (File) finalResult.get(i);
                System.out.println(
"  Directory found: " + f.getAbsolutePath());
            }

            System.out.println(
"=======================================\n");
        }


        
/*
         * (non-Javadoc)
         * 
         * @see org.apache.commons.io.DirectoryWalker#handleDirectory(java.io.File,
         *      int, java.util.Collection)
         
*/

        
protected boolean handleDirectory(File directory, int depth,
                Collection results) 
throws IOException {

            System.out.println(
"\nSearching under directory: "
                    
+ directory.getAbsolutePath());
            
            
// Just test for cancel operation
            
// Cancel when meet WebRoot folder, so all directories under this
            
// folder are supposed not to be check
             if (FilenameUtils.equalsNormalizedOnSystem("WebRoot", directory
                    .getName())) 
{
                
throw new CancelException(directory, depth);
            }

            
            
if (FilenameUtils.equalsNormalizedOnSystem(targetDirName, directory
                    .getName())) 
{
                results.add(directory);
            }

            
return true;
        }


        
/**
         * Cancel.
         
*/

        
public void cancel() {
            cancelled 
= true;
        }


        
/*
         * (non-Javadoc)
         * 
         * @see org.apache.commons.io.DirectoryWalker#handleIsCancelled(java.io.File,
         *      int, java.util.Collection)
         
*/

        
protected boolean handleIsCancelled(File file, int depth,
                Collection results) 
{
            
return cancelled;
        }


        
/*
         * (non-Javadoc)
         * 
         * @see org.apache.commons.io.DirectoryWalker#handleCancelled(java.io.File,
         *      java.util.Collection,
         *      org.apache.commons.io.DirectoryWalker.CancelException)
         
*/

        
protected void handleCancelled(File startDirectory, Collection results,
                CancelException cancel) 
{
            
if (cancelled) {
                cancel();
            }

            System.out.println(
"\nCancelled by external or interal thread");
            finalResult 
= (List<File>) results;
        }

    }


}


-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要尽力打好一手烂牌。
posted on 2010-03-31 23:45 Paul Lin 阅读(2558) 评论(1)  编辑  收藏 所属分类: J2SE


FeedBack:
# re: 【Java基础专题】IO与文件读写---使用DirectoryWalker和FileFilterUtils进行搜索
2010-04-01 11:02 | 隔叶黄莺-2
不错,以后可能用得着。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2010年3月>
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿(21)

随笔分类

随笔档案

BlogJava热点博客

好友博客

搜索

  •  

最新评论

阅读排行榜

评论排行榜