root/branches/Abonament/BazaReklam.Updater/ICSharpCode.SharpZipLib/Core/FileSystemScanner.cs @ 759

Wersja 597, 15.1 KB (wprowadzona przez marek, 17 years temu)

re #165

Line 
1// FileSystemScanner.cs
2//
3// Copyright 2005 John Reilly
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18//
19// Linking this library statically or dynamically with other modules is
20// making a combined work based on this library.  Thus, the terms and
21// conditions of the GNU General Public License cover the whole
22// combination.
23//
24// As a special exception, the copyright holders of this library give you
25// permission to link this library with independent modules to produce an
26// executable, regardless of the license terms of these independent
27// modules, and to copy and distribute the resulting executable under
28// terms of your choice, provided that you also meet, for each linked
29// independent module, the terms and conditions of the license of that
30// module.  An independent module is a module which is not derived from
31// or based on this library.  If you modify this library, you may extend
32// this exception to your version of the library, but you are not
33// obligated to do so.  If you do not wish to do so, delete this
34// exception statement from your version.
35
36
37using System;
38using System.IO;
39
40namespace ICSharpCode.SharpZipLib.Core
41{
42        #region EventArgs
43        /// <summary>
44        /// Event arguments for scanning.
45        /// </summary>
46        public class ScanEventArgs : EventArgs
47        {
48                #region Constructors
49                /// <summary>
50                /// Initialise a new instance of <see cref="ScanEventArgs"/>
51                /// </summary>
52                /// <param name="name">The file or directory name.</param>
53                public ScanEventArgs(string name)
54                {
55                        name_ = name;
56                }
57                #endregion
58               
59                /// <summary>
60                /// The file or directory name for this event.
61                /// </summary>
62                public string Name
63                {
64                        get { return name_; }
65                }
66               
67                /// <summary>
68                /// Get set a value indicating if scanning should continue or not.
69                /// </summary>
70                public bool ContinueRunning
71                {
72                        get { return continueRunning_; }
73                        set { continueRunning_ = value; }
74                }
75               
76                #region Instance Fields
77                string name_;
78                bool continueRunning_ = true;
79                #endregion
80        }
81
82        /// <summary>
83        /// Event arguments during processing of a single file or directory.
84        /// </summary>
85        public class ProgressEventArgs : EventArgs
86        {
87                #region Constructors
88                /// <summary>
89                /// Initialise a new instance of <see cref="ScanEventArgs"/>
90                /// </summary>
91                /// <param name="name">The file or directory name if known.</param>
92                /// <param name="processed">The number of bytes processed so far</param>
93                /// <param name="target">The total number of bytes to process, 0 if not known</param>
94                public ProgressEventArgs(string name, long processed, long target)
95                {
96                        name_ = name;
97                        processed_ = processed;
98                        target_ = target;
99                }
100                #endregion
101               
102                /// <summary>
103                /// The name for this event if known.
104                /// </summary>
105                public string Name
106                {
107                        get { return name_; }
108                }
109               
110                /// <summary>
111                /// Get set a value indicating wether scanning should continue or not.
112                /// </summary>
113                public bool ContinueRunning
114                {
115                        get { return continueRunning_; }
116                        set { continueRunning_ = value; }
117                }
118
119                /// <summary>
120                /// Get a percentage representing how much of the <see cref="Target"></see> has been processed
121                /// </summary>
122                /// <value>0.0 to 100.0 percent; 0 if target is not known.</value>
123                public float PercentComplete
124                {
125                        get
126                        {
127                                if (target_ <= 0)
128                                {
129                                        return 0;
130                                }
131                                else
132                                {
133                                        return ((float)processed_ / (float)target_) * 100.0f;
134                                }
135                        }
136                }
137               
138                /// <summary>
139                /// The number of bytes processed so far
140                /// </summary>
141                public long Processed
142                {
143                        get { return processed_; }
144                }
145
146                /// <summary>
147                /// The number of bytes to process.
148                /// </summary>
149                /// <remarks>Target may be 0 or negative if the value isnt known.</remarks>
150                public long Target
151                {
152                        get { return target_; }
153                }
154               
155                #region Instance Fields
156                string name_;
157                long processed_;
158                long target_;
159                bool continueRunning_ = true;
160                #endregion
161        }
162
163        /// <summary>
164        /// Event arguments for directories.
165        /// </summary>
166        public class DirectoryEventArgs : ScanEventArgs
167        {
168                #region Constructors
169                /// <summary>
170                /// Initialize an instance of <see cref="DirectoryEventArgs"></see>.
171                /// </summary>
172                /// <param name="name">The name for this directory.</param>
173                /// <param name="hasMatchingFiles">Flag value indicating if any matching files are contained in this directory.</param>
174                public DirectoryEventArgs(string name, bool hasMatchingFiles)
175                        : base (name)
176                {
177                        hasMatchingFiles_ = hasMatchingFiles;
178                }
179                #endregion
180               
181                /// <summary>
182                /// Get a value indicating if the directory contains any matching files or not.
183                /// </summary>
184                public bool HasMatchingFiles
185                {
186                        get { return hasMatchingFiles_; }
187                }
188               
189                #region Instance Fields
190                bool hasMatchingFiles_;
191                #endregion
192        }
193       
194        /// <summary>
195        /// Arguments passed when scan failures are detected.
196        /// </summary>
197        public class ScanFailureEventArgs : EventArgs
198        {
199                #region Constructors
200                /// <summary>
201                /// Initialise a new instance of <see cref="ScanFailureEventArgs"></see>
202                /// </summary>
203                /// <param name="name">The name to apply.</param>
204                /// <param name="e">The exception to use.</param>
205                public ScanFailureEventArgs(string name, Exception e)
206                {
207                        name_ = name;
208                        exception_ = e;
209                        continueRunning_ = true;
210                }
211                #endregion
212               
213                /// <summary>
214                /// The applicable name.
215                /// </summary>
216                public string Name
217                {
218                        get { return name_; }
219                }
220               
221                /// <summary>
222                /// The applicable exception.
223                /// </summary>
224                public Exception Exception
225                {
226                        get { return exception_; }
227                }
228               
229                /// <summary>
230                /// Get / set a value indicating wether scanning should continue.
231                /// </summary>
232                public bool ContinueRunning
233                {
234                        get { return continueRunning_; }
235                        set { continueRunning_ = value; }
236                }
237               
238                #region Instance Fields
239                string name_;
240                Exception exception_;
241                bool continueRunning_;
242                #endregion
243        }
244       
245        #endregion
246       
247        #region Delegates
248        /// <summary>
249        /// Delegate invoked before starting to process a directory.
250        /// </summary>
251        public delegate void ProcessDirectoryHandler(object sender, DirectoryEventArgs e);
252       
253        /// <summary>
254        /// Delegate invoked before starting to process a file.
255        /// </summary>
256        /// <param name="sender">The source of the event</param>
257        /// <param name="e">The event arguments.</param>
258        public delegate void ProcessFileHandler(object sender, ScanEventArgs e);
259
260        /// <summary>
261        /// Delegate invoked during processing of a file or directory
262        /// </summary>
263        /// <param name="sender">The source of the event</param>
264        /// <param name="e">The event arguments.</param>
265        public delegate void ProgressHandler(object sender, ProgressEventArgs e);
266
267        /// <summary>
268        /// Delegate invoked when a file has been completely processed.
269        /// </summary>
270        /// <param name="sender">The source of the event</param>
271        /// <param name="e">The event arguments.</param>
272        public delegate void CompletedFileHandler(object sender, ScanEventArgs e);
273       
274        /// <summary>
275        /// Delegate invoked when a directory failure is detected.
276        /// </summary>
277        /// <param name="sender">The source of the event</param>
278        /// <param name="e">The event arguments.</param>
279        public delegate void DirectoryFailureHandler(object sender, ScanFailureEventArgs e);
280       
281        /// <summary>
282        /// Delegate invoked when a file failure is detected.
283        /// </summary>
284        /// <param name="sender">The source of the event</param>
285        /// <param name="e">The event arguments.</param>
286        public delegate void FileFailureHandler(object sender, ScanFailureEventArgs e);
287        #endregion
288
289        /// <summary>
290        /// FileSystemScanner provides facilities scanning of files and directories.
291        /// </summary>
292        public class FileSystemScanner
293        {
294                #region Constructors
295                /// <summary>
296                /// Initialise a new instance of <see cref="FileSystemScanner"></see>
297                /// </summary>
298                /// <param name="filter">The <see cref="PathFilter">file filter</see> to apply when scanning.</param>
299                public FileSystemScanner(string filter)
300                {
301                        fileFilter_ = new PathFilter(filter);
302                }
303               
304                /// <summary>
305                /// Initialise a new instance of <see cref="FileSystemScanner"></see>
306                /// </summary>
307                /// <param name="fileFilter">The <see cref="PathFilter">file filter</see> to apply.</param>
308                /// <param name="directoryFilter">The <see cref="PathFilter"> directory filter</see> to apply.</param>
309                public FileSystemScanner(string fileFilter, string directoryFilter)
310                {
311                        fileFilter_ = new PathFilter(fileFilter);
312                        directoryFilter_ = new PathFilter(directoryFilter);
313                }
314               
315                /// <summary>
316                /// Initialise a new instance of <see cref="FileSystemScanner"></see>
317                /// </summary>
318                /// <param name="fileFilter">The file <see cref="IScanFilter">filter</see> to apply.</param>
319                public FileSystemScanner(IScanFilter fileFilter)
320                {
321                        fileFilter_ = fileFilter;
322                }
323               
324                /// <summary>
325                /// Initialise a new instance of <see cref="FileSystemScanner"></see>
326                /// </summary>
327                /// <param name="fileFilter">The file <see cref="IScanFilter">filter</see>  to apply.</param>
328                /// <param name="directoryFilter">The directory <see cref="IScanFilter">filter</see>  to apply.</param>
329                public FileSystemScanner(IScanFilter fileFilter, IScanFilter directoryFilter)
330                {
331                        fileFilter_ = fileFilter;
332                        directoryFilter_ = directoryFilter;
333                }
334                #endregion
335
336                #region Delegates
337                /// <summary>
338                /// Delegate to invoke when a directory is processed.
339                /// </summary>
340                public ProcessDirectoryHandler ProcessDirectory;
341               
342                /// <summary>
343                /// Delegate to invoke when a file is processed.
344                /// </summary>
345                public ProcessFileHandler ProcessFile;
346
347                /// <summary>
348                /// Delegate to invoke when processing for a file has finished.
349                /// </summary>
350                public CompletedFileHandler CompletedFile;
351
352                /// <summary>
353                /// Delegate to invoke when a directory failure is detected.
354                /// </summary>
355                public DirectoryFailureHandler DirectoryFailure;
356               
357                /// <summary>
358                /// Delegate to invoke when a file failure is detected.
359                /// </summary>
360                public FileFailureHandler FileFailure;
361                #endregion
362
363                /// <summary>
364                /// Raise the DirectoryFailure event.
365                /// </summary>
366                /// <param name="directory">The directory name.</param>
367                /// <param name="e">The exception detected.</param>
368                bool OnDirectoryFailure(string directory, Exception e)
369                {
370            DirectoryFailureHandler handler = DirectoryFailure;
371            bool result = (handler != null);
372            if ( result ) {
373                                ScanFailureEventArgs args = new ScanFailureEventArgs(directory, e);
374                                handler(this, args);
375                                alive_ = args.ContinueRunning;
376                        }
377            return result;
378                }
379               
380                /// <summary>
381                /// Raise the FileFailure event.
382                /// </summary>
383                /// <param name="file">The file name.</param>
384                /// <param name="e">The exception detected.</param>
385                bool OnFileFailure(string file, Exception e)
386                {
387            FileFailureHandler handler = FileFailure;
388
389            bool result = (handler != null);
390
391                        if ( result ){
392                                ScanFailureEventArgs args = new ScanFailureEventArgs(file, e);
393                                FileFailure(this, args);
394                                alive_ = args.ContinueRunning;
395                        }
396            return result;
397                }
398
399                /// <summary>
400                /// Raise the ProcessFile event.
401                /// </summary>
402                /// <param name="file">The file name.</param>
403                void OnProcessFile(string file)
404                {
405                        ProcessFileHandler handler = ProcessFile;
406
407                        if ( handler!= null ) {
408                                ScanEventArgs args = new ScanEventArgs(file);
409                                handler(this, args);
410                                alive_ = args.ContinueRunning;
411                        }
412                }
413
414                /// <summary>
415                /// Raise the complete file event
416                /// </summary>
417                /// <param name="file">The file name</param>
418                void OnCompleteFile(string file)
419                {
420                        CompletedFileHandler handler = CompletedFile;
421
422                        if (handler != null)
423                        {
424                                ScanEventArgs args = new ScanEventArgs(file);
425                                handler(this, args);
426                                alive_ = args.ContinueRunning;
427                        }
428                }
429
430                /// <summary>
431                /// Raise the ProcessDirectory event.
432                /// </summary>
433                /// <param name="directory">The directory name.</param>
434                /// <param name="hasMatchingFiles">Flag indicating if the directory has matching files.</param>
435                void OnProcessDirectory(string directory, bool hasMatchingFiles)
436                {
437                        ProcessDirectoryHandler handler = ProcessDirectory;
438
439                        if ( handler != null ) {
440                                DirectoryEventArgs args = new DirectoryEventArgs(directory, hasMatchingFiles);
441                                handler(this, args);
442                                alive_ = args.ContinueRunning;
443                        }
444                }
445
446                /// <summary>
447                /// Scan a directory.
448                /// </summary>
449                /// <param name="directory">The base directory to scan.</param>
450                /// <param name="recurse">True to recurse subdirectories, false to scan a single directory.</param>
451                public void Scan(string directory, bool recurse)
452                {
453                        alive_ = true;
454                        ScanDir(directory, recurse);
455                }
456               
457                void ScanDir(string directory, bool recurse)
458                {
459
460                        try {
461                                string[] names = System.IO.Directory.GetFiles(directory);
462                                bool hasMatch = false;
463                                for (int fileIndex = 0; fileIndex < names.Length; ++fileIndex) {
464                                        if ( !fileFilter_.IsMatch(names[fileIndex]) ) {
465                                                names[fileIndex] = null;
466                                        } else {
467                                                hasMatch = true;
468                                        }
469                                }
470                               
471                                OnProcessDirectory(directory, hasMatch);
472                               
473                                if ( alive_ && hasMatch ) {
474                                        foreach (string fileName in names) {
475                                                try {
476                                                        if ( fileName != null ) {
477                                                                OnProcessFile(fileName);
478                                                                if ( !alive_ ) {
479                                                                        break;
480                                                                }
481                                                        }
482                                                }
483                                                catch (Exception e) {
484                            if (!OnFileFailure(fileName, e)) {
485                                throw;
486                            }
487                                                }
488                                        }
489                                }
490                        }
491                        catch (Exception e) {
492                if (!OnDirectoryFailure(directory, e)) {
493                    throw;
494                }
495                        }
496
497                        if ( alive_ && recurse ) {
498                                try {
499                                        string[] names = System.IO.Directory.GetDirectories(directory);
500                                        foreach (string fulldir in names) {
501                                                if ((directoryFilter_ == null) || (directoryFilter_.IsMatch(fulldir))) {
502                                                        ScanDir(fulldir, true);
503                                                        if ( !alive_ ) {
504                                                                break;
505                                                        }
506                                                }
507                                        }
508                                }
509                                catch (Exception e) {
510                    if (!OnDirectoryFailure(directory, e)) {
511                        throw;
512                    }
513                                }
514                        }
515                }
516               
517                #region Instance Fields
518                /// <summary>
519                /// The file filter currently in use.
520                /// </summary>
521                IScanFilter fileFilter_;
522                /// <summary>
523                /// The directory filter currently in use.
524                /// </summary>
525                IScanFilter directoryFilter_;
526                /// <summary>
527                /// Flag indicating if scanning should continue running.
528                /// </summary>
529                bool alive_;
530                #endregion
531        }
532}
Notatka: Zobacz TracBrowser aby uzyskać więcej informacji.