這兩個搜索類都是以內部類的方式嵌入客戶端的,客戶端接收客戶的參數,然后通過一個后臺線程來進行搜索,等待子線程完成搜索后(join方法),再打印搜索結果。
注意這個過程是可以被cancel的。cancel主要有2種情況。外部cancel:外部線程通過調用內部類的cancel()方法。內部cancel:在handleDirectory、handleFile中主動拋出CancelException。
walk方法在每次執行前、后都會檢查當前是否有cancel指令發出(checkIfCancelled ---> handleIsCancelled),如果有那么默認立刻拋出CancelException,然后調用handleCancelled方法。
這里搜索實現類被實現為一個內部類,目的是不想暴露內部的搜索過程邏輯,只對外暴露客戶端接口。其次內部采用線程實現,方便充當客戶端的外部類可以在必要時cancel這個內部線程操作,而且當搜索過程漫長時不會造成界面假死(GUI界面)。
在搜索過程中,我們可以對搜索到文件、資源進行處理,例如:刪除,重命名,移動等。最常見的一個應用就是批量刪除搜索到的文件。例如.svn目錄或日志文件



































【一】從根目錄開始,查詢(指定目錄下)指定的文件
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
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88



89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

【二】從根目錄開始,查找指定的目錄

















































































































































































































-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。