mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
fileUtils.cpp
Go to the documentation of this file.
1 /** \file fileUtils.cpp
2  * \brief Definitions of utilities for working with files
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup fileutils
7  *
8  */
9 
10 //***********************************************************************//
11 // Copyright 2020 Jared R. Males (jaredmales@gmail.com)
12 //
13 // This file is part of mxlib.
14 //
15 // mxlib is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // mxlib is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
27 //***********************************************************************//
28 
29 #include "ioutils/fileUtils.hpp"
30 
31 #include <iostream>
32 #include <string>
33 #include <vector>
34 #include <sstream>
35 #include <libgen.h>
36 #include <cmath>
37 #include <algorithm>
38 
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <unistd.h>
42 
43 #include <boost/filesystem.hpp>
44 
45 using namespace boost::filesystem;
46 
47 namespace mx
48 {
49 namespace ioutils
50 {
51 
52 int createDirectories( const std::string & path )
53 {
54  //Use the non throwing version and silently ignore EEXIST errors
55  boost::system::error_code ec;
56  boost::filesystem::create_directories(path, ec);
57  if(ec.value() != boost::system::errc::success && ec.value() != boost::system::errc::file_exists)
58  {
59  return -1;
60  }
61 
62  return 0;
63 }
64 
65 std::string pathStem(const std::string & fname)
66 {
67  boost::filesystem::path p(fname);
68  return p.stem().string();
69 }
70 
71 std::string pathFilename( const std::string & fname)
72 {
73  boost::filesystem::path p(fname);
74  return p.filename().string();
75 }
76 
77 std::string parentPath(const std::string & fname)
78 {
79  boost::filesystem::path p(fname);
80  return p.parent_path().string();
81 }
82 
83 
84 
85 std::vector<std::string> getFileNames( const std::string & directory,
86  const std::string & prefix,
87  const std::string & substr,
88  const std::string & extension
89  )
90 {
91  typedef std::vector<path> vec; // store paths,
92 
93  std::vector<std::string> vect;
94  if( exists(directory) )
95  {
96  if(is_directory(directory) )
97  {
98  vec v; // so we can sort them later
99 
100  copy(directory_iterator(directory), directory_iterator(), back_inserter(v));
101 
102  std::sort(v.begin(), v.end()); // sort, since directory iteration
103  // is not ordered on some file systems
104 
105  auto it = v.begin();
106  auto it_end = v.end();
107 
108  while(it != it_end)
109  {
110  bool inc = true;
111 
112  if(extension != "")
113  {
114  if(it->extension() != extension)
115  {
116  inc = false;
117  }
118  }
119 
120  if(prefix != "" && inc)
121  {
122  std::string p = it->filename().generic_string();
123 
124  if( p.size() < prefix.size() )
125  {
126  inc = false;
127  }
128  else
129  {
130  if(p.compare(0, prefix.size(), prefix) != 0)
131  {
132  inc = false;
133  }
134  }
135  }
136 
137  if(substr != "" && inc)
138  {
139  std::string p = it->filename().generic_string();
140  if(p.find(substr) == std::string::npos)
141  {
142  inc = false;
143  }
144  }
145 
146  if(inc)
147  {
148  vect.push_back(it->native());
149  }
150 
151  ++it;
152  }
153  }
154  else
155  {
156  std::cerr << directory << " is not a directory\n";
157  }
158 
159  }
160  else
161  {
162  std::cerr << "directory " << directory << " does not exist\n";
163  }
164 
165  return vect;
166 }
167 
168 std::vector<std::string> getFileNames( const std::string & directory,
169  const std::string & extension
170  )
171 {
172  return getFileNames(directory, "", "", extension);
173 }
174 
175 std::vector<std::string> getFileNames( const std::string & directory )
176 {
177  return getFileNames(directory, "", "", "");
178 }
179 
180 
181 std::string fileNamePrependAppend( const std::string & fname,
182  const std::string & prepend,
183  const std::string & append
184  )
185 {
186  std::string dir, base, ext;
187 
188  path p = fname;
189  dir = p.parent_path().string();
190  base = p.stem().string();
191  ext = p.extension().string();
192 
193 
194  return dir +'/' + prepend + base + append + ext;
195 
196 
197 }
198 
199 std::string fileNameAppend( const std::string & fname,
200  const std::string & append
201  )
202 {
203  return fileNamePrependAppend(fname, "", append);
204 }
205 
206 std::string fileNamePrepend( const std::string & fname,
207  const std::string & prepend
208  )
209 {
210  return fileNamePrependAppend(fname, prepend, "");
211 }
212 
213 std::string getSequentialFilename( const std::string & basename,
214  const std::string & extension,
215  const int startat,
216  const int ndigit
217  )
218 {
219  //int maxdig = 1;
220  //for(int j=0;j<ndigit;++j) maxdig *= 10;
221  int maxdig = pow(10, ndigit);
222 
223  char formstr[64];
224  snprintf(formstr, sizeof(formstr), "%%0%dd", ndigit);
225 
226  char digstr[64];
227  int i = startat;
228 
229  std::stringstream outn;
230 
231  snprintf(digstr,sizeof(digstr),formstr, i);
232 
233  outn << basename;
234  outn << digstr;
235  outn << extension;
236 
237  while(boost::filesystem::exists(outn.str()) && i < maxdig)
238  {
239  ++i;
240  outn.str("");
241 
242  snprintf(digstr,sizeof(digstr), formstr, i);
243 
244  outn << basename;
245  outn << digstr;
246 
247  outn << extension;
248  }
249 
250  return outn.str();
251 }
252 
253 off_t fileSize( int fd )
254 {
255  if (fd == -1)
256  {
257  return -1;
258  }
259 
260  struct stat stbuf;
261 
262  if ((fstat(fd, &stbuf) != 0) || (!S_ISREG(stbuf.st_mode)))
263  {
264  return -1;
265  }
266 
267  return stbuf.st_size;
268 
269 }
270 
271 off_t fileSize( FILE * f )
272 {
273  return fileSize(fileno(f));
274 }
275 
276 
277 } //namespace ioutils
278 } //namespace mx
279 
Declarations of utilities for working with files.
std::string fileNamePrepend(const std::string &fname, const std::string &prepend)
Prepend strings to a file name, leaving the directory and extension unaltered.
Definition: fileUtils.cpp:206
std::string getSequentialFilename(const std::string &basename, const std::string &extension="", const int startat=0, int ndigit=4)
Get the next file in a numbered sequence.
Definition: fileUtils.cpp:213
std::string fileNamePrependAppend(const std::string &fname, const std::string &prepend, const std::string &append)
Prepend and/or append strings to a file name, leaving the directory and extension unaltered.
Definition: fileUtils.cpp:181
std::string fileNameAppend(const std::string &fname, const std::string &append)
Append a string to a file name, leaving the directory and extension unaltered.
Definition: fileUtils.cpp:199
std::vector< std::string > getFileNames(const std::string &directory, const std::string &prefix, const std::string &substr, const std::string &extension)
Get a list of file names from the specified directory, specifying a prefix, a substring to match,...
Definition: fileUtils.cpp:85
int createDirectories(const std::string &path)
Create a directory or directories.
Definition: fileUtils.cpp:52
std::string parentPath(const std::string &fname)
Get the parent path from a filename.
Definition: fileUtils.cpp:77
std::string pathStem(const std::string &fname)
Get the stem of the filename.
Definition: fileUtils.cpp:65
off_t fileSize(int fd)
Get the size in bytes of a file.
Definition: fileUtils.cpp:253
std::string pathFilename(const std::string &fname)
Get the base filename.
Definition: fileUtils.cpp:71
The mxlib c++ namespace.
Definition: mxError.hpp:107