1 package com.explosion.utilities;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.ArrayList;
6 import java.util.List;
7
8 import com.explosion.utilities.regex.RegExpFileAndDirectoryFilter;
9 import com.explosion.utilities.regex.RegExpFileNameFilter;
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 /***
32 * A really handy class which will pass back to you all the files in a directory
33 * recursively one at a time whenever one is asked for.
34 *
35 * @author Stephen Created on May 5, 2004
36 */
37 public class FileIterator
38 {
39
40
41
42 private boolean recursive = false;
43 private boolean excludeDirectories = true;
44 private boolean caseSensitive = false;
45 private boolean hasNext = true;
46
47 private String fileNamePattern = null;
48 private RegExpFileAndDirectoryFilter regExpAndDirectoryFilter;
49 private RegExpFileNameFilter regExpFilter;
50 private List fileList = new ArrayList();
51 private FileIterator activeIterator;
52 private File currentFile = null;
53 private File fileToReturn = null;
54
55 private int index = 0;
56 private int recursionLevel = 0;
57 private int numberOfFiles = 0;
58 private int numberOfDirectories = 0;
59
60 /***
61 * Creates a file iterator object with the provided arguments
62 * @param directory directory to look in
63 * @param pattern regexp pattern of filename to look for
64 * @param caseSensitive regexp matching to be case sensitive or not
65 * @param recursive find files recursively
66 * @param excludesDirectories will not return any directories if set to true
67 */
68 public FileIterator(String directory, String fileNamePattern, boolean caseSensitive, boolean recursive, boolean excludeDirectories) throws IOException
69 {
70 this.recursive = recursive;
71 this.caseSensitive = caseSensitive;
72 this.excludeDirectories = excludeDirectories;
73 this.fileNamePattern = (fileNamePattern == null ? "" : fileNamePattern);
74 regExpFilter = new RegExpFileNameFilter(fileNamePattern, caseSensitive);
75 File sourceDirectory = new File(directory);
76
77
78 if (!sourceDirectory.exists())
79 throw new IOException("Unable to find path specified for creating a list of files: " + directory);
80
81 if (!sourceDirectory.isDirectory())
82 throw new IOException("Path specified for creating a list of files is not a directory : " + directory);
83
84 if (!recursive && excludeDirectories)
85 {
86
87 regExpAndDirectoryFilter = new RegExpFileAndDirectoryFilter(regExpFilter);
88 File[] files = sourceDirectory.listFiles(regExpAndDirectoryFilter);
89 for (int i = 0; i < files.length; i++)
90 fileList.add(files[i]);
91
92
93 }
94 else
95 {
96 File[] files = sourceDirectory.listFiles();
97 for (int i = 0; i < files.length; i++)
98 {
99 if (files[i].isDirectory() || regExpFilter.accept(files[i].getParentFile(), files[i].getName()))
100 {
101 fileList.add(files[i]);
102 if (files[i].isDirectory())
103 numberOfDirectories++;
104 else
105 numberOfFiles++;
106 }
107 }
108
109 }
110
111
112 if (fileList.size() > 0)
113 {
114 index = 0;
115 currentFile = (File) fileList.get(index);
116 }
117 }
118
119 /***
120 * Returns a boolean stating whether there are any more files in the
121 * iterator.
122 *
123 * @return
124 */
125 public boolean hasNext() throws IOException
126 {
127 if (currentFile == null)
128 return false;
129 else
130 {
131 fileToReturn = getNext();
132 return fileToReturn != null;
133 }
134 }
135
136 public File getNext() throws IOException
137 {
138 if (currentFile.isDirectory())
139 {
140 if (recursive)
141 {
142
143
144
145 if (activeIterator == null)
146 {
147 activeIterator = new FileIterator(currentFile.getAbsolutePath(), fileNamePattern, caseSensitive, recursive, excludeDirectories);
148 activeIterator.recursionLevel=recursionLevel++;
149 }
150
151
152 if (activeIterator.hasNext())
153 {
154 return activeIterator.next();
155 }
156 else
157 {
158
159 activeIterator = null;
160
161
162 if (excludeDirectories)
163 {
164
165 transitionIterator();
166 if (currentFile == null)
167 {
168
169 return null;
170 }
171 else
172 {
173
174 return getNext();
175 }
176 }
177 else
178 {
179
180 }
181 }
182 }
183 else
184 {
185
186
187
188 }
189 }
190
191 File returnValue = currentFile;
192 transitionIterator();
193
194 return returnValue;
195 }
196
197 private String getRecursionLevelString()
198 {
199 String string = new String();
200 for (int i=0;i<recursionLevel;i++)
201 {
202 string += " ";
203 }
204 return string;
205 }
206
207 /***
208 * This method incremenets the iterator and looks after the
209 * index, hasNext and currentFile variables
210 *
211 */
212 private void transitionIterator()
213 {
214 index++;
215 if (index < fileList.size())
216 {
217
218 currentFile = (File) fileList.get(index);
219 }
220 else
221 {
222 currentFile = null;
223 }
224 }
225
226 /***
227 * Returns the next file in this iterator
228 *
229 * @return
230 */
231 public File next() throws IOException
232 {
233 return fileToReturn;
234 }
235
236 /***
237 * At best a rough guide. It basically just gives you the result of the progress through the top level of files.
238 * @return int percent complete
239 */
240 public int getPercentComplete()
241 {
242 if (fileList.size() == 0)
243 return 100;
244 else
245 return ( index / fileList.size() ) * 100;
246 }
247
248 /***
249 * @return Returns the caseSensitive.
250 */
251 public boolean isCaseSensitive()
252 {
253 return caseSensitive;
254 }
255 /***
256 * @return Returns the excludeDirectories.
257 */
258 public boolean isExcludeDirectories()
259 {
260 return excludeDirectories;
261 }
262 /***
263 * @return Returns the numberOfDirectories.
264 */
265 public int getNumberOfDirectories()
266 {
267 return numberOfDirectories;
268 }
269 /***
270 * @return Returns the numberOfFiles.
271 */
272 public int getNumberOfFiles()
273 {
274 return numberOfFiles;
275 }
276
277 /***
278 * Returns the total number of items in this iterator
279 * @return
280 */
281 public int getNumberOfItems()
282 {
283 return fileList.size();
284 }
285 /***
286 * @return Returns the recursive.
287 */
288 public boolean isRecursive()
289 {
290 return recursive;
291 }
292 }