SST 15.0
Structural Simulation Toolkit
filesystem.h
1// Copyright 2009-2025 NTESS. Under the terms
2// of Contract DE-NA0003525 with NTESS, the U.S.
3// Government retains certain rights in this software.
4//
5// Copyright (c) 2009-2025, NTESS
6// All rights reserved.
7//
8// This file is part of the SST software package. For license
9// information, see the LICENSE file in the top level directory of the
10// distribution.
11
12#ifndef SST_CORE_FILESYSTEM_H
13#define SST_CORE_FILESYSTEM_H
14
15#include <cstdio>
16#include <iostream>
17#include <mutex>
18#include <stdexcept>
19
20// REMOVE ME
21#include <filesystem>
22
23namespace SST {
24namespace Util {
25
26
27/**
28 Class used to manage files and directories. One of the features is
29 that you can set the base directory to be used for all files and
30 directories specified with a relative path.
31 */
32class Filesystem
33{
34public:
35 Filesystem() = default;
36
37 /**
38 Set the base path to be use when relative paths are used. If a
39 relative path is passed into this function, then the current
40 working directory will be used as the base path. When the
41 base_path is set, the class will check to see if the path
42 already exists, and if not, whether or not the user has
43 permissions to create the directory. If the directory doesn't
44 exist and the user doesn't have permission to create it, the
45 function will return false and thee base_path will remain
46 unchanged. If the directory doesn't exist and the user has
47 permissions to create it, the directory will be created on
48 demand.
49
50 @param base_path Path to set as the base path. The path can be
51 absolute or relative, and a path starting with ~/ with the ~
52 expanded to the user's home directory.
53
54 @return True if path is valid and either exists and is writable
55 by the user or can be created, false otherwise.
56 */
57 bool setBasePath(const std::string& base_path);
58
59 /**
60 This function will ensure a directory exists, and if it doesn't
61 already exist, it will create it. If the directory starts with
62 / or ~/ (where ~ represents your home directory) then the path
63 will be considered absolute. Otherwise, the path will be
64 relative to base path set using setBasePath(), or the current
65 working directory if a base path has not been set, or the
66 filename begins with ./ or ../. All intermediate directories
67 that don't exist will be created.
68
69 @param path Path to verify or create
70
71 @param strip_filename Set to true if input is a file and you
72 need to strip the filename to get the directory name. Default
73 is false.
74
75 @return false if directory exists but is not writable, true
76 otherwise
77
78 @throws std::filesystem::filesystem_error Thrown when the
79 directory does not exist and the function tries to create it
80 but sees an underlying OS API error (see
81 std::filesystem::create_directories()); the most likely cause
82 is a permissions error, or an identically named file.
83
84 @throws std::invalid_argument Thrown when the passed in path
85 starts with ~/ and the home directory cannot be determined.
86 */
87 bool ensureDirectoryExists(std::filesystem::path p, bool strip_filename = false);
88
89
90 /**
91 Creates a unique directory. If the specified directory already
92 exists, the function will append _1 to the directory name. If
93 that is also taken, it will increment the ID until it finds the
94 lowest index that is not used. The function will also create
95 any directory in the path that does not already exist, but only
96 the final directory will be made unique.
97
98 @param dir_name Name of directory to create. Directory can be
99 relative or absolute and all intermediate paths that don't
100 exist will be created. The unique name only applies to the last
101 level directory.
102
103 @return Absolute path of the created directory
104
105 @throws std::filesystem::filesystem_error Thrown when the call
106 sees an underlying OS API error (see
107 std::filesystem::create_directories()); the most likely cause
108 is a permissions error, or an file named identically to one of
109 the directory names that needs to be created.
110
111 @throws std::invalid_argument Thrown when the passed in path
112 starts with ~/ and the home directory cannot be determined.
113
114 */
115 std::string createUniqueDirectory(std::filesystem::path dir_name);
116
117
118 /**
119 Open a file using std::fopen(). If the passed-in path is
120 relative, it will be relative to the path set using
121 setBasePath(). If setBasePath() was not called, then it will
122 be relative to the current working directory. The FILE*
123 returned from this function can be closed by using
124 std::fclose().
125
126 @param filename Name of file to open.
127
128 @param mode read/write mode as defined by std::fopen()
129
130 @return FILE* to opened file
131 */
132 FILE* fopen(const std::string& filename, const char* mode);
133
134
135 /**
136 Get the absolute path for a directory or name. If the directory
137 starts with / or ~/ (where ~ represents your home directory)
138 then the path will be considered absolute. Otherwise, the path
139 will be relative to the base_path, or the current working
140 directory if no base_path was set or the path starts with ./ or
141 ../
142
143 @param path Path to turn into an absolute path, based on the
144 base_path of the filesystem object
145
146 @return returns the absolute path
147
148 @throws std::invalid_argument Thrown when base_path is not
149 absolute (in format, there is no check to see if the directory
150 actually exists) and the passed in path is relative. Also
151 thrown when the passed in path starts with ~/ and the home
152 directory cannot be determined.
153 */
154 std::string getAbsolutePath(const std::string& path);
155
156 /**
157 Open a file using ofstream. If the passed-in path is relative,
158 it will be relative to the path set using setBasePath(). If
159 setBasePath() was not called, then it will be relative to the
160 current working directory.
161
162 @param filename Name of file to open
163
164 @param mode read/write mode as defined by std::ofstream
165
166 @return ofstream object representing the new opened file
167 */
168 std::ofstream ofstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::out);
169
170
171 /**
172 Get the base_path set by setBasePath
173
174 @return base_path set by setBasePath. This will be an absolute
175 path
176 */
177 std::string getBasePath() const { return base_path_.string(); }
178
179
180 /**
181 Get the absolute path for a directory or name. If the directory
182 starts with / or ~/ (where ~ represents your home directory)
183 then the path will be considered absolute. Otherwise, the path
184 will be relative to the set base_path, or the current working
185 directory if no base_path was set, or the path starts with ./
186 or ../
187
188 @param path Path to turn into an absolute path
189
190 @param base_path Path to use as the base path for relative
191 paths passed into the path parameter. If an empty string is
192 passed in, then the current working directory will be used as
193 the base_path (default behavior if you don't pass in a
194 base_path). base_path must be an absolute path and cannot
195 include a ~
196
197 @throws std::invalid_argument Thrown when base_path is not
198 absolute (in format, there is no check to see if the directory
199 actually exists) and the passed in path is relative. Also
200 thrown when the passed in path starts with ~/ and the home
201 directory cannot be determined.
202 */
203 static std::string getAbsolutePath(const std::string& path, std::string base_path);
204
205 /**
206 Gets a random file name for use as a temporary file or
207 directory
208 */
209 static std::string getRandomName(size_t length = 8);
210
211private:
212 std::filesystem::path base_path_;
213 static std::mutex create_mutex_;
214};
215
216void test_filesystem();
217
218} // end namespace Util
219} // end namespace SST
220
221#endif // SST_CORE_FILESYSTEM_H
bool ensureDirectoryExists(std::filesystem::path p, bool strip_filename=false)
This function will ensure a directory exists, and if it doesn't already exist, it will create it.
Definition filesystem.cc:144
std::string createUniqueDirectory(std::filesystem::path dir_name)
Creates a unique directory.
Definition filesystem.cc:168
FILE * fopen(const std::string &filename, const char *mode)
Open a file using std::fopen().
Definition filesystem.cc:209
static std::string getRandomName(size_t length=8)
Gets a random file name for use as a temporary file or directory.
Definition filesystem.cc:265
bool setBasePath(const std::string &base_path)
Set the base path to be use when relative paths are used.
Definition filesystem.cc:102
std::ofstream ofstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
Open a file using ofstream.
Definition filesystem.cc:217
std::string getAbsolutePath(const std::string &path)
Get the absolute path for a directory or name.
Definition filesystem.cc:199
std::string getBasePath() const
Get the base_path set by setBasePath.
Definition filesystem.h:177