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