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