Main MRPT website > C++ reference for MRPT 1.9.9
CDirectoryExplorer.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/config.h>
13 
14 #ifdef MRPT_OS_WINDOWS
15 #ifdef _MSC_VER
16 #include <sys/utime.h>
17 #endif
18 #include <io.h>
19 #include <windows.h>
20 #include <direct.h>
21 #else
22 #include <sys/types.h>
23 #include <dirent.h>
24 #include <unistd.h>
25 #include <time.h>
26 #include <utime.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <cstring>
30 #endif
31 
32 #include <queue>
33 #include <algorithm>
34 #include <iostream>
35 #include <cstdio>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 
40 #include <mrpt/system/filesystem.h>
41 
42 using namespace mrpt::system;
43 using namespace std;
44 
45 /*---------------------------------------------------------------
46  explore
47  ---------------------------------------------------------------*/
49  const string& path, const unsigned long in_mask, TFileInfoList& outList)
50 {
52 
53  unsigned long mask = in_mask;
54 
55  outList.clear();
56 
57  // The path terminated in "/" or "\\"
58  string searchPath(path);
59  if (searchPath.size())
60  if (searchPath[searchPath.size() - 1] != '\\' &&
61  searchPath[searchPath.size() - 1] != '/')
62  {
63 #ifdef MRPT_OS_WINDOWS
64  searchPath += '\\';
65 #else
66  searchPath.push_back('/');
67 #endif
68  }
69 
70 // cout << "searchPath:"<<searchPath<<endl;
71 
72 #ifdef MRPT_OS_WINDOWS
73  // ====================
74  // WINDOWS VERSION
75  // ====================
76  WIN32_FIND_DATAA f;
77  TFileInfo newEntry;
78 
79  string searchPath_mask = searchPath + string("*.*");
80 
81  HANDLE h = FindFirstFileA(searchPath_mask.c_str(), &f);
82  if (h == INVALID_HANDLE_VALUE)
83  THROW_EXCEPTION("Error starting exploration! (does path exist?)");
84 
85  // Include the FILE_ATTRIB_ARCHIVE flag for files:
86  if (mask & FILE_ATTRIB_ARCHIVE) mask |= FILE_ATTRIBUTE_NORMAL;
87  do
88  {
89  if ((mask & f.dwFileAttributes) != 0) // Passes the user masks:
90  {
91  // File name:
92  newEntry.name = string(f.cFileName);
93 
94  // Complete file path:
95  newEntry.wholePath = searchPath;
96  newEntry.wholePath += newEntry.name;
97 
98  // File size:
99  newEntry.fileSize = ((uint64_t)f.nFileSizeLow) +
100  (((uint64_t)f.nFileSizeHigh) << 32);
101 
102  // File times:
103  struct stat statDat;
104  if (stat(newEntry.wholePath.c_str(), &statDat))
105  {
106  FindClose(h);
108  "Cannot get stat for file: '%s'",
109  newEntry.wholePath.c_str())
110  }
111 
112  newEntry.modTime = statDat.st_mtime;
113  newEntry.accessTime = statDat.st_atime;
114 
115  // Flags:
116  newEntry.isDir = 0 != (statDat.st_mode & _S_IFDIR);
117  newEntry.isSymLink =
118  false; // (We donnot look for this in Windows, by now...)
119 
120  // Save:
121  outList.push_back(newEntry);
122  }
123  } while (FindNextFileA(h, &f));
124 
125  FindClose(h); // Ignore possible errors..
126 
127 // Done
128 #else
129  // ====================
130  // LINUX VERSION
131  // ====================
132  TFileInfo newEntry;
133  struct dirent* ent;
134 
135  DIR* dir = opendir(searchPath.c_str());
136  if (!dir) THROW_EXCEPTION("Error starting exploration! (does path exist?)");
137 
138  while ((ent = readdir(dir)) != nullptr)
139  {
140  if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, ".."))
141  {
142  // File name:
143  newEntry.name = string(ent->d_name);
144 
145  // Complete file path:
146  newEntry.wholePath = searchPath;
147  newEntry.wholePath += newEntry.name;
148 
149  // File times:
150  struct stat statDat, lstatDat;
151  if (stat(newEntry.wholePath.c_str(), &statDat))
152  {
153  closedir(dir);
155  "Cannot get stat for file: '%s'",
156  newEntry.wholePath.c_str())
157  }
158 
159  newEntry.modTime = statDat.st_mtime;
160  newEntry.accessTime = statDat.st_atime;
161 
162  // Flags:
163  newEntry.isDir = S_ISDIR(statDat.st_mode);
164 
165  if (((mask & FILE_ATTRIB_ARCHIVE) != 0 && !newEntry.isDir) ||
166  ((mask & FILE_ATTRIB_DIRECTORY) != 0 && newEntry.isDir))
167  {
168  // File size:
169  newEntry.fileSize = (intmax_t)statDat.st_size;
170 
171  // Is it a symbolic link?? Need to call "lstat":
172  if (!lstat(newEntry.wholePath.c_str(), &lstatDat))
173  {
174  newEntry.isSymLink = S_ISLNK(lstatDat.st_mode);
175  }
176  else
177  newEntry.isSymLink = false;
178 
179  // Save:
180  outList.push_back(newEntry);
181  }
182  }
183  }
184 
185  closedir(dir);
186 
187 // Done
188 #endif
189 
190  MRPT_END
191 }
192 
193 // Auxiliary function to order by name, ascending
197 {
198  return a.wholePath < b.wholePath;
199 }
203 {
204  return a.wholePath > b.wholePath;
205 }
206 
207 /*---------------------------------------------------------------
208  sortByName
209  ---------------------------------------------------------------*/
211  TFileInfoList& lstFiles, bool ascendingOrder)
212 {
213  std::sort(
214  lstFiles.begin(), lstFiles.end(),
216 }
217 
218 /*---------------------------------------------------------------
219  filterByExtension
220  ---------------------------------------------------------------*/
222  TFileInfoList& lstFiles, const std::string& extension)
223 {
224  int i, n = (int)lstFiles.size();
225  for (i = n - 1; i >= 0; i--)
226  {
227  if (0 !=
228  os::_strcmpi(
229  mrpt::system::extractFileExtension(lstFiles[i].name).c_str(),
230  extension.c_str()))
231  {
232  // Does not match:
233  lstFiles.erase(lstFiles.begin() + i);
234  }
235  }
236 }
static void filterByExtension(TFileInfoList &lstFiles, const std::string &extension)
Remove from the list of files those whose extension does not coincide (without case) with the given o...
static void explore(const std::string &path, const unsigned long mask, TFileInfoList &outList)
The path of the directory to examine must be passed to this constructor, among the According to the f...
GLenum GLint GLuint mask
Definition: glext.h:4050
std::string wholePath
The whole file path.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
#define THROW_EXCEPTION(msg)
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
GLenum GLsizei n
Definition: glext.h:5074
bool cmpFileEntriesName_Desc(const CDirectoryExplorer::TFileInfo &a, const CDirectoryExplorer::TFileInfo &b)
STL namespace.
This represents the information about each file.
#define FILE_ATTRIB_ARCHIVE
time_t accessTime
Access and modification times.
uint64_t fileSize
The size of the file in bytes.
std::deque< TFileInfo > TFileInfoList
The list type used in "explore".
#define MRPT_END
int32_t intmax_t
GLubyte GLubyte b
Definition: glext.h:6279
std::string extractFileExtension(const std::string &filePath, bool ignore_gz=false)
Extract the extension of a filename.
Definition: filesystem.cpp:97
GLsizei const GLchar ** string
Definition: glext.h:4101
static void sortByName(TFileInfoList &lstFiles, bool ascendingOrder=true)
Sort the file entries by name, in ascending or descending order.
std::string name
The file name (without the whole path).
#define MRPT_START
unsigned __int64 uint64_t
Definition: rptypes.h:50
#define FILE_ATTRIB_DIRECTORY
GLuint const GLchar * name
Definition: glext.h:4054
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
int _strcmpi(const char *str1, const char *str2) noexcept
An OS-independent version of strcmpi.
Definition: os.cpp:319
bool cmpFileEntriesName_Asc(const CDirectoryExplorer::TFileInfo &a, const CDirectoryExplorer::TFileInfo &b)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019