mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
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
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <unistd.h>
41
42#include <filesystem>
43
44namespace mx
45{
46namespace ioutils
47{
48
49namespace fileUtilsDetail
50{
51
52namespace
53{
54
55void noOperationFailure( operation )
56{
57}
58
59void noErrorCodeFailure( operation, std::error_code & )
60{
61}
62
63} // namespace
64
65operationHookT &operationHook()
66{
67 static operationHookT hook = noOperationFailure;
68 return hook;
69}
70
71errorCodeHookT &errorCodeHook()
72{
73 static errorCodeHookT hook = noErrorCodeFailure;
74 return hook;
75}
76
77} // namespace fileUtilsDetail
78
79template bool exists<verbose::d>( const std::string &, error_t & );
80
81template bool dir_exists_is<verbose::d>( const std::string &, error_t & );
82
83error_t createDirectories( const std::string &path )
84{
85 // Use the non throwing version and silently ignore EEXIST errors
86 std::error_code ec;
87 std::filesystem::create_directories( path, ec );
88 fileUtilsDetail::errorCodeHook()( fileUtilsDetail::operation::createDirectories, ec );
89 if( ec.value() != 0 && ec.value() != EEXIST )
90 {
91 mx::error_t errc = errno2error_t( ec.value() );
92 if( errc == error_t::error )
93 {
95 }
96 return errc;
97 }
98
99 return error_t::noerror;
100}
101
102std::string pathStem( const std::string &fname )
103{
104 std::filesystem::path p( fname );
105 return p.stem().string();
106}
107
108std::string pathFilename( const std::string &fname )
109{
110 std::filesystem::path p( fname );
111 return p.filename().string();
112}
113
114std::string parentPath( const std::string &fname )
115{
116 std::filesystem::path p( fname );
117 return p.parent_path().string();
118}
119
120template error_t getFileNames<verbose::d>( std::vector<std::string> &fileNames,
121 const std::string &directory,
122 const std::string &prefix,
123 const std::string &substr,
124 const std::string &extension );
125
126std::string fileNamePrependAppend( const std::string &fname, const std::string &prepend, const std::string &append )
127{
128 std::string dir, base, ext;
129
130 std::filesystem::path p = fname;
131 dir = p.parent_path().string();
132 base = p.stem().string();
133 ext = p.extension().string();
134
135 return dir + '/' + prepend + base + append + ext;
136}
137
138std::string fileNameAppend( const std::string &fname, const std::string &append )
139{
140 return fileNamePrependAppend( fname, "", append );
141}
142
143std::string fileNamePrepend( const std::string &fname, const std::string &prepend )
144{
145 return fileNamePrependAppend( fname, prepend, "" );
146}
147
148std::string
149getSequentialFilename( const std::string &basename, const std::string &extension, const int startat, const int ndigit )
150{
151 // int maxdig = 1;
152 // for(int j=0;j<ndigit;++j) maxdig *= 10;
153 int maxdig = pow( 10, ndigit );
154
155 char formstr[64];
156 snprintf( formstr, sizeof( formstr ), "%%0%dd", ndigit );
157
158 char digstr[64];
159 int i = startat;
160
161 std::stringstream outn;
162
163 snprintf( digstr, sizeof( digstr ), formstr, i );
164
165 outn << basename;
166 outn << digstr;
167 outn << extension;
168
169 while( std::filesystem::exists( outn.str() ) && i < maxdig )
170 {
171 ++i;
172 outn.str( "" );
173
174 snprintf( digstr, sizeof( digstr ), formstr, i );
175
176 outn << basename;
177 outn << digstr;
178
179 outn << extension;
180 }
181
182 return outn.str();
183}
184
185off_t fileSize( int fd )
186{
187 if( fd == -1 )
188 {
189 return -1;
190 }
191
192 struct stat stbuf;
193
194 if( ( fstat( fd, &stbuf ) != 0 ) || ( !S_ISREG( stbuf.st_mode ) ) )
195 {
196 return -1;
197 }
198
199 return stbuf.st_size;
200}
201
202off_t fileSize( FILE *f )
203{
204 return fileSize( fileno( f ) );
205}
206
207} // namespace ioutils
208} // namespace mx
Declarations of utilities for working with files.
error_t
The mxlib error codes.
Definition error_t.hpp:26
static constexpr error_t errno2error_t(const int &err)
Convert an errno code to error_t.
Definition error_t.hpp:2056
@ noerror
No error has occurred.
Definition error_t.hpp:27
@ filesystem
A general filesystem error occurred.
Definition error_t.hpp:39
@ error
A general error has occurred.
Definition error_t.hpp:28
std::string fileNamePrepend(const std::string &fname, const std::string &prepend)
Prepend strings to a file name, leaving the directory and extension unaltered.
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.
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.
std::string fileNameAppend(const std::string &fname, const std::string &append)
Append a string to a file name, leaving the directory and extension unaltered.
bool exists(const std::string &path, mx::error_t &errc)
Check if a path exists.
error_t createDirectories(const std::string &path)
Create a directory or directories.
Definition fileUtils.cpp:83
bool dir_exists_is(const std::string &dir, mx::error_t &errc)
Check if a path exists and is a directory.
std::string parentPath(const std::string &fname)
Get the parent path from a filename.
std::string pathStem(const std::string &fname)
Get the stem of the filename.
off_t fileSize(int fd)
Get the size in bytes of a file.
std::string pathFilename(const std::string &fname)
Get the base filename.
The mxlib c++ namespace.
Definition mxlib.hpp:37