Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

root/trunk/tango/io/FileScan.d

Revision 2913, 6.8 kB (checked in by kris, 1 year ago)

the big toString change

  • Property svn:mime-type set to text/x-dsrc
  • Property svn:eol-style set to native
Line 
1 /*******************************************************************************
2
3         copyright:      Copyright (c) 2004 Kris Bell. All rights reserved
4
5         license:        BSD style: $(LICENSE)
6
7         version:        Jun 2004: Initial release
8         version:        Dec 2006: Pacific release
9
10         author:         Kris
11
12 *******************************************************************************/
13
14 module tango.io.FileScan;
15
16 public  import tango.io.FilePath;
17
18 private import tango.core.Exception;
19
20 /*******************************************************************************
21
22         Recursively scan files and directories, adding filtered files to
23         an output structure as we go. This can be used to produce a list
24         of subdirectories and the files contained therein. The following
25         example lists all files with suffix ".d" located via the current
26         directory, along with the folders containing them:
27         ---
28         auto scan = new FileScan;
29
30         scan (".", ".d");
31
32         Stdout.formatln ("{} Folders", scan.folders.length);
33         foreach (folder; scan.folders)
34                  Stdout.formatln ("{}", folder);
35
36         Stdout.formatln ("\n{} Files", scan.files.length);
37         foreach (file; scan.files)
38                  Stdout.formatln ("{}", file);
39         ---
40
41         This is unlikely the most efficient method to scan a vast number of
42         files, but operates in a convenient manner
43         
44 *******************************************************************************/
45
46 class FileScan
47 {      
48         alias sweep     opCall;
49
50         FilePath[]      fileSet;
51         char[][]        errorSet;
52         FilePath[]      folderSet;
53        
54         /***********************************************************************
55
56             Alias for Filter delegate. Accepts a FilePath & a bool as
57             arguments and returns a bool.
58
59             The FilePath argument represents a file found by the scan,
60             and the bool whether the FilePath represents a folder.
61
62             The filter should return true, if matched by the filter. Note
63             that returning false where the path is a folder will result
64             in all files contained being ignored. To always recurse folders,
65             do something like this:
66             ---
67             return (isDir || match (fp.name));
68             ---
69
70         ***********************************************************************/
71
72         alias FilePath.Filter Filter;
73
74        /***********************************************************************
75
76                 Return all the errors found in the last scan
77
78         ***********************************************************************/
79
80         public char[][] errors ()
81         {
82                 return errorSet;
83         }
84
85         /***********************************************************************
86
87                 Return all the files found in the last scan
88
89         ***********************************************************************/
90
91         public FilePath[] files ()
92         {
93                 return fileSet;
94         }
95
96         /***********************************************************************
97         
98                 Return all directories found in the last scan
99
100         ***********************************************************************/
101
102         public FilePath[] folders ()
103         {
104                 return folderSet;
105         }
106
107         /***********************************************************************
108
109                 Sweep a set of files and directories from the given parent
110                 path, with no filtering applied
111         
112         ***********************************************************************/
113        
114         FileScan sweep (char[] path, bool recurse=true)
115         {
116                 return sweep (path, cast(Filter) null, recurse);
117         }
118
119         /***********************************************************************
120
121                 Sweep a set of files and directories from the given parent
122                 path, where the files are filtered by the given suffix
123         
124         ***********************************************************************/
125        
126         FileScan sweep (char[] path, char[] match, bool recurse=true)
127         {
128                 return sweep (path, (FilePath fp, bool isDir)
129                              {return isDir || fp.suffix == match;}, recurse);
130         }
131
132         /***********************************************************************
133
134                 Sweep a set of files and directories from the given parent
135                 path, where the files are filtered by the provided delegate
136
137         ***********************************************************************/
138        
139         FileScan sweep (char[] path, Filter filter, bool recurse=true)
140         {
141                 errorSet = null, fileSet = folderSet = null;
142                 return scan (new FilePath(path), filter, recurse);
143         }
144
145         /***********************************************************************
146
147                 Internal routine to locate files and sub-directories. We
148                 skip entries with names composed only of '.' characters.
149
150         ***********************************************************************/
151
152         private FileScan scan (FilePath folder, Filter filter, bool recurse)
153         {
154                 try {
155                     auto paths = folder.toList (filter);
156                
157                     auto count = fileSet.length;
158                     foreach (path; paths)
159                              if (! path.isFolder)
160                                    fileSet ~= path;
161                              else
162                                 if (recurse)
163                                     scan (path, filter, recurse);
164                
165                     // add packages only if there's something in them
166                     if (fileSet.length > count)
167                         folderSet ~= folder;
168
169                     } catch (IOException e)
170                              errorSet ~= e.toString;
171                 return this;
172         }
173 }
174
175
176 /*******************************************************************************
177
178 *******************************************************************************/
179
180 debug (FileScan)
181 {
182         import tango.io.Stdout;
183
184         void main()
185         {
186                 auto scan = new FileScan;
187
188                 scan (".");
189
190                 Stdout.formatln ("{} Folders", scan.folders.length);
191                 foreach (folder; scan.folders)
192                          Stdout (folder).newline;
193
194                 Stdout.formatln ("\n{} Files", scan.files.length);
195                 foreach (file; scan.files)
196                          Stdout (file).newline;
197
198                 Stdout.formatln ("\n{} Errors", scan.errors.length);
199                 foreach (error; scan.errors)
200                          Stdout (error).newline;
201         }
202 }
Note: See TracBrowser for help on using the browser.