OLD | NEW |
| (Empty) |
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.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 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 const WIN32_FIND_DATA& find_data() const { return find_data_; } | |
57 #elif defined(OS_POSIX) | |
58 const struct stat& stat() const { return stat_; } | |
59 #endif | |
60 | |
61 private: | |
62 friend class FileEnumerator; | |
63 | |
64 #if defined(OS_WIN) | |
65 WIN32_FIND_DATA find_data_; | |
66 #elif defined(OS_POSIX) | |
67 struct stat stat_; | |
68 FilePath filename_; | |
69 #endif | |
70 }; | |
71 | |
72 enum FileType { | |
73 FILES = 1 << 0, | |
74 DIRECTORIES = 1 << 1, | |
75 INCLUDE_DOT_DOT = 1 << 2, | |
76 #if defined(OS_POSIX) | |
77 SHOW_SYM_LINKS = 1 << 4, | |
78 #endif | |
79 }; | |
80 | |
81 // |root_path| is the starting directory to search for. It may or may not end | |
82 // in a slash. | |
83 // | |
84 // If |recursive| is true, this will enumerate all matches in any | |
85 // subdirectories matched as well. It does a breadth-first search, so all | |
86 // files in one directory will be returned before any files in a | |
87 // subdirectory. | |
88 // | |
89 // |file_type|, a bit mask of FileType, specifies whether the enumerator | |
90 // should match files, directories, or both. | |
91 // | |
92 // |pattern| is an optional pattern for which files to match. This | |
93 // works like shell globbing. For example, "*.txt" or "Foo???.doc". | |
94 // However, be careful in specifying patterns that aren't cross platform | |
95 // since the underlying code uses OS-specific matching routines. In general, | |
96 // Windows matching is less featureful than others, so test there first. | |
97 // If unspecified, this will match all files. | |
98 // NOTE: the pattern only matches the contents of root_path, not files in | |
99 // recursive subdirectories. | |
100 // TODO(erikkay): Fix the pattern matching to work at all levels. | |
101 FileEnumerator(const FilePath& root_path, | |
102 bool recursive, | |
103 int file_type); | |
104 FileEnumerator(const FilePath& root_path, | |
105 bool recursive, | |
106 int file_type, | |
107 const FilePath::StringType& pattern); | |
108 ~FileEnumerator(); | |
109 | |
110 // Returns the next file or an empty string if there are no more results. | |
111 // | |
112 // The returned path will incorporate the |root_path| passed in the | |
113 // constructor: "<root_path>/file_name.txt". If the |root_path| is absolute, | |
114 // then so will be the result of Next(). | |
115 FilePath Next(); | |
116 | |
117 // Write the file info into |info|. | |
118 FileInfo GetInfo() const; | |
119 | |
120 private: | |
121 // Returns true if the given path should be skipped in enumeration. | |
122 bool ShouldSkip(const FilePath& path); | |
123 | |
124 #if defined(OS_WIN) | |
125 // True when find_data_ is valid. | |
126 bool has_find_data_; | |
127 WIN32_FIND_DATA find_data_; | |
128 HANDLE find_handle_; | |
129 #elif defined(OS_POSIX) | |
130 | |
131 // Read the filenames in source into the vector of DirectoryEntryInfo's | |
132 static bool ReadDirectory(std::vector<FileInfo>* entries, | |
133 const FilePath& source, bool show_links); | |
134 | |
135 // The files in the current directory | |
136 std::vector<FileInfo> directory_entries_; | |
137 | |
138 // The next entry to use from the directory_entries_ vector | |
139 size_t current_directory_entry_; | |
140 #endif | |
141 | |
142 FilePath root_path_; | |
143 bool recursive_; | |
144 int file_type_; | |
145 FilePath::StringType pattern_; // Empty when we want to find everything. | |
146 | |
147 // A stack that keeps track of which subdirectories we still need to | |
148 // enumerate in the breadth-first search. | |
149 std::stack<FilePath> pending_paths_; | |
150 | |
151 DISALLOW_COPY_AND_ASSIGN(FileEnumerator); | |
152 }; | |
153 | |
154 } // namespace base | |
155 | |
156 #endif // BASE_FILES_FILE_ENUMERATOR_H_ | |
OLD | NEW |