Home | History | Annotate | Download | only in files
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_FILES_FILE_ENUMERATOR_H_
      6 #define BASE_FILES_FILE_ENUMERATOR_H_
      7 
      8 #include <stack>
      9 #include <vector>
     10 
     11 #include "base/base_export.h"
     12 #include "base/basictypes.h"
     13 #include "base/files/file_path.h"
     14 #include "base/time/time.h"
     15 #include "build/build_config.h"
     16 
     17 #if defined(OS_WIN)
     18 #include <windows.h>
     19 #elif defined(OS_POSIX)
     20 #include <sys/stat.h>
     21 #include <unistd.h>
     22 #endif
     23 
     24 namespace base {
     25 
     26 // A class for enumerating the files in a provided path. The order of the
     27 // results is not guaranteed.
     28 //
     29 // This is blocking. Do not use on critical threads.
     30 //
     31 // Example:
     32 //
     33 //   base::FileEnumerator enum(my_dir, false, base::FileEnumerator::FILES,
     34 //                             FILE_PATH_LITERAL("*.txt"));
     35 //   for (base::FilePath name = enum.Next(); !name.empty(); name = enum.Next())
     36 //     ...
     37 class BASE_EXPORT FileEnumerator {
     38  public:
     39   // Note: copy & assign supported.
     40   class BASE_EXPORT FileInfo {
     41    public:
     42     FileInfo();
     43     ~FileInfo();
     44 
     45     bool IsDirectory() const;
     46 
     47     // The name of the file. This will not include any path information. This
     48     // is in constrast to the value returned by FileEnumerator.Next() which
     49     // includes the |root_path| passed into the FileEnumerator constructor.
     50     FilePath GetName() const;
     51 
     52     int64 GetSize() const;
     53     Time GetLastModifiedTime() const;
     54 
     55 #if defined(OS_WIN)
     56     // Note that the cAlternateFileName (used to hold the "short" 8.3 name)
     57     // of the WIN32_FIND_DATA will be empty. Since we don't use short file
     58     // names, we tell Windows to omit it which speeds up the query slightly.
     59     const WIN32_FIND_DATA& find_data() const { return find_data_; }
     60 #elif defined(OS_POSIX)
     61     const struct stat& stat() const { return stat_; }
     62 #endif
     63 
     64    private:
     65     friend class FileEnumerator;
     66 
     67 #if defined(OS_WIN)
     68     WIN32_FIND_DATA find_data_;
     69 #elif defined(OS_POSIX)
     70     struct stat stat_;
     71     FilePath filename_;
     72 #endif
     73   };
     74 
     75   enum FileType {
     76     FILES                 = 1 << 0,
     77     DIRECTORIES           = 1 << 1,
     78     INCLUDE_DOT_DOT       = 1 << 2,
     79 #if defined(OS_POSIX)
     80     SHOW_SYM_LINKS        = 1 << 4,
     81 #endif
     82   };
     83 
     84   // |root_path| is the starting directory to search for. It may or may not end
     85   // in a slash.
     86   //
     87   // If |recursive| is true, this will enumerate all matches in any
     88   // subdirectories matched as well. It does a breadth-first search, so all
     89   // files in one directory will be returned before any files in a
     90   // subdirectory.
     91   //
     92   // |file_type|, a bit mask of FileType, specifies whether the enumerator
     93   // should match files, directories, or both.
     94   //
     95   // |pattern| is an optional pattern for which files to match. This
     96   // works like shell globbing. For example, "*.txt" or "Foo???.doc".
     97   // However, be careful in specifying patterns that aren't cross platform
     98   // since the underlying code uses OS-specific matching routines.  In general,
     99   // Windows matching is less featureful than others, so test there first.
    100   // If unspecified, this will match all files.
    101   // NOTE: the pattern only matches the contents of root_path, not files in
    102   // recursive subdirectories.
    103   // TODO(erikkay): Fix the pattern matching to work at all levels.
    104   FileEnumerator(const FilePath& root_path,
    105                  bool recursive,
    106                  int file_type);
    107   FileEnumerator(const FilePath& root_path,
    108                  bool recursive,
    109                  int file_type,
    110                  const FilePath::StringType& pattern);
    111   ~FileEnumerator();
    112 
    113   // Returns the next file or an empty string if there are no more results.
    114   //
    115   // The returned path will incorporate the |root_path| passed in the
    116   // constructor: "<root_path>/file_name.txt". If the |root_path| is absolute,
    117   // then so will be the result of Next().
    118   FilePath Next();
    119 
    120   // Write the file info into |info|.
    121   FileInfo GetInfo() const;
    122 
    123  private:
    124   // Returns true if the given path should be skipped in enumeration.
    125   bool ShouldSkip(const FilePath& path);
    126 
    127 #if defined(OS_WIN)
    128   // True when find_data_ is valid.
    129   bool has_find_data_;
    130   WIN32_FIND_DATA find_data_;
    131   HANDLE find_handle_;
    132 #elif defined(OS_POSIX)
    133 
    134   // Read the filenames in source into the vector of DirectoryEntryInfo's
    135   static bool ReadDirectory(std::vector<FileInfo>* entries,
    136                             const FilePath& source, bool show_links);
    137 
    138   // The files in the current directory
    139   std::vector<FileInfo> directory_entries_;
    140 
    141   // The next entry to use from the directory_entries_ vector
    142   size_t current_directory_entry_;
    143 #endif
    144 
    145   FilePath root_path_;
    146   bool recursive_;
    147   int file_type_;
    148   FilePath::StringType pattern_;  // Empty when we want to find everything.
    149 
    150   // A stack that keeps track of which subdirectories we still need to
    151   // enumerate in the breadth-first search.
    152   std::stack<FilePath> pending_paths_;
    153 
    154   DISALLOW_COPY_AND_ASSIGN(FileEnumerator);
    155 };
    156 
    157 }  // namespace base
    158 
    159 #endif  // BASE_FILES_FILE_ENUMERATOR_H_
    160