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);
}
【一】从根目录开始,查询(指定目录下)指定的文件
1
package example.io;
2
3
import java.io.File;
4
import java.io.IOException;
5
import java.util.ArrayList;
6
import java.util.Collection;
7
import java.util.List;
8
9
import org.apache.commons.io.DirectoryWalker;
10
import org.apache.commons.io.FilenameUtils;
11
import org.apache.commons.io.filefilter.FileFilterUtils;
12
13
/** *//**
14
* The Class FileSearcher.
15
*/
16
public 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 阅读(2564)
评论(1) 编辑 收藏 所属分类:
J2SE