25 using std::stringstream;
36 const string FileSystem::composeURI(
const string& pathName,
const string& fileName) {
37 return pathName +
"/" + fileName;
42 auto _pathName = pathName;
43 if (StringTools::endsWith(_pathName,
"/") ==
false) _pathName+=
"/";
46 for (
const auto& entry: std::filesystem::directory_iterator(std::filesystem::path((
const char8_t*)_pathName.c_str()))) {
47 auto u8FileName = entry.path().filename().u8string();
48 string fileName(u8FileName.size(), 0);
49 for (
auto i = 0; i < u8FileName.size(); i++) fileName[i] = u8FileName[i];
51 if (filter !=
nullptr && filter->
accept(pathName, fileName) ==
false)
continue;
53 Console::printLine(
"FileSystem::list(): Filter::accept(): " + pathName +
"/" + fileName +
": " +
string(exception.what()));
56 files.push_back(fileName);
59 throw FileSystemException(
"Unable to list path: " + pathName +
": " +
string(exception.what()));
63 sort(files.begin(), files.end());
66 if (
isDrive(_pathName) ==
false && _pathName.empty() ==
false && _pathName !=
"/") {
67 if (filter ==
nullptr || filter->
accept(pathName,
"..") ==
true) files.insert(files.begin(),
"..");
71 if (addDrives ==
true) {
72 for (
char drive =
'A'; drive <=
'Z'; drive++) {
77 if (
exists(fileName +
"/") ==
true) files.insert(files.begin() + (drive -
'C'), fileName);
79 Console::printLine(
"FileSystem::list(): fileExists(): " + pathName +
"/" + fileName +
": " +
string(exception.what()));
88 auto status = std::filesystem::status(std::filesystem::path((
const char8_t*)pathName.c_str()));
89 return std::filesystem::is_directory(status);
91 throw FileSystemException(
"Unable to check if path: " + pathName +
": " +
string(exception.what()));
98 return StringTools::regexMatch(pathName,
"^[a-zA-Z]{1}\\:.*$");
103 return std::filesystem::exists(std::filesystem::path((
const char8_t*)uri.c_str()));
105 throw FileSystemException(
"Unable to check if file exists: " + uri +
": " +
string(exception.what()));
113 return std::filesystem::file_size(std::filesystem::path((
const char8_t*)
composeURI(pathName, fileName).c_str()));
115 throw FileSystemException(
"Unable to determine file size: " + fileName +
": " +
string(exception.what()));
122 ifstream ifs(std::filesystem::path((
const char8_t*)
composeURI(pathName, fileName).c_str()));
123 if (ifs.is_open() ==
false) {
124 throw FileSystemException(
"Unable to open file for reading(" + to_string(errno) +
"): " + pathName +
"/" + fileName);
126 stringstream stringStream;
127 stringStream << ifs.rdbuf();
129 return (stringStream.str());
133 ofstream ofs(std::filesystem::path((
const char8_t*)
composeURI(pathName, fileName).c_str()));
134 if (ofs.is_open() ==
false) {
135 throw FileSystemException(
"Unable to open file for writing(" + to_string(errno) +
"): " + pathName +
"/" + fileName);
144 ifstream ifs(std::filesystem::path((
const char8_t*)
composeURI(pathName, fileName).c_str()), ifstream::binary);
145 if (ifs.is_open() ==
false) {
146 throw FileSystemException(
"Unable to open file for reading(" + to_string(errno) +
"): " + pathName +
"/" + fileName);
148 ifs.seekg( 0, ios::end );
149 size_t size = ifs.tellg();
150 content.resize(size);
151 ifs.seekg(0, ios::beg);
152 ifs.read((
char*)content.data(), size);
157 ofstream ofs(std::filesystem::path((
const char8_t*)
composeURI(pathName, fileName).c_str()), ofstream::binary);
158 if (ofs.is_open() ==
false) {
159 throw FileSystemException(
"Unable to open file for writing(" + to_string(errno) +
"): " + pathName +
"/" + fileName);
161 ofs.write((
char*)content.data(), content.size());
167 ifstream ifs(std::filesystem::path((
const char8_t*)
composeURI(pathName, fileName).c_str()));
168 if(ifs.is_open() ==
false) {
169 throw FileSystemException(
"Unable to open file for reading(" + to_string(errno) +
"): " + pathName +
"/" + fileName);
173 while (getline(ifs, line)) {
174 content.push_back(StringTools::replace(line,
"\r",
""));
182 ofstream ofs(std::filesystem::path((
const char8_t*)
composeURI(pathName, fileName).c_str()), ofstream::binary);
183 if(ofs.is_open() ==
false) {
184 throw FileSystemException(
"Unable to open file for writing(" + to_string(errno) +
"): " + pathName +
"/" + fileName);
187 for (
auto i = 0; i < content.size(); i++) {
188 ofs << (content.at(i)) <<
"\n";
196 string unixPathName = StringTools::replace(pathName,
"\\",
"/");
197 string unixFileName = StringTools::replace(fileName,
"\\",
"/");
200 auto pathString =
composeURI(unixPathName, unixFileName);
203 vector<string> pathComponents;
211 for (
auto i = 0; i < pathComponents.size(); i++) {
212 auto pathComponent = pathComponents[i];
213 if (pathComponent ==
".") {
214 pathComponents[i].clear();
216 if (pathComponent ==
"..") {
217 pathComponents[i].clear();
219 for (
int pathComponentReplaced = 0; pathComponentReplaced < 1 && j >= 0; ) {
220 if (pathComponents[j].empty() ==
false) {
221 pathComponents[j].clear();
222 pathComponentReplaced++;
230 string canonicalPath =
"";
231 bool slash = StringTools::startsWith(pathString,
"/");
232 for (
auto i = 0; i < pathComponents.size(); i++) {
233 auto pathComponent = pathComponents[i];
234 if (pathComponent.empty() ==
true) {
237 canonicalPath = canonicalPath + (slash ==
true?
"/":
"") + pathComponent;
243 auto canonicalPathString = canonicalPath.empty() ==
true?
"/":canonicalPath;
253 return canonicalPathString;
258 auto u8Cwd = std::filesystem::current_path().u8string();
259 string cwd(u8Cwd.size(), 0);
260 for (
auto i = 0; i < u8Cwd.size(); i++) cwd[i] = u8Cwd[i];
271 return std::filesystem::current_path(std::filesystem::path((
const char8_t*)pathName.c_str()));
273 throw FileSystemException(
"Unable to change path: " + pathName +
": " +
string(exception.what()));
278 auto unixFileName = StringTools::replace(uri,
'\\',
'/');
279 auto lastPathSeparator = StringTools::lastIndexOf(unixFileName,
'/');
280 if (lastPathSeparator == -1)
return ".";
281 return StringTools::substring(unixFileName, 0, lastPathSeparator);
285 auto unixFileName = StringTools::replace(uri,
'\\',
'/');
286 auto lastPathSeparator = StringTools::lastIndexOf(unixFileName,
'/');
287 if (lastPathSeparator == -1)
return uri;
288 return StringTools::substring(unixFileName, lastPathSeparator + 1, unixFileName.length());
292 auto idx = fileName.rfind(
'.');
293 if (idx == string::npos) {
296 return fileName.substr(0, idx);
302 if (std::filesystem::create_directory(std::filesystem::path((
const char8_t*)pathName.c_str())) ==
false) {
306 throw FileSystemException(
"Unable to create path: " + pathName +
": " +
string(exception.what()));
312 if (recursive ==
false) {
313 if (std::filesystem::remove(std::filesystem::path((
const char8_t*)pathName.c_str())) ==
false) {
317 if (std::filesystem::remove_all(std::filesystem::path((
const char8_t*)pathName.c_str())) ==
false) {
322 throw FileSystemException(
"Unable to remove path: " + pathName +
": " +
string(exception.what()));
328 if (std::filesystem::remove(std::filesystem::path((
const char8_t*)
composeURI(pathName, fileName).c_str())) ==
false) {
332 throw FileSystemException(
"Unable to remove file: " + pathName +
"/" + fileName +
": " +
string(exception.what()));
338 std::filesystem::rename(std::filesystem::path((
const char8_t*)fileNameFrom.c_str()), std::filesystem::path((
const char8_t*)fileNameTo.c_str()));
340 throw FileSystemException(
"Unable to rename file: " + fileNameFrom +
" -> " + fileNameTo +
": " +
string(exception.what()));
static const string removeFileExtension(const string &fileName)
Remove file extension, e.g.
static bool isDrive(const string &uri)
Check if file is a drive (applies to Microsoft Windows only)
static void setContentFromString(const string &pathName, const string &fileName, const string &content)
Set content from string.
static const string composeURI(const string &pathName, const string &fileName)
Compose URI from path name and file name.
static const string getPathName(const string &uri)
Get path name.
static const string getCanonicalURI(const string &pathName, const string &fileName)
Get canonical URI from given path name and file name.
static void createPath(const string &pathName)
Create path.
static void list(const string &pathName, vector< string > &files, FileNameFilter *filter=nullptr, bool addDrives=false)
List files for given path and filter by a file name filter if not null.
static void changePath(const string &pathName)
Change path.
static void removePath(const string &pathName, bool recursive)
Remove path.
static void setContent(const string &pathName, const string &fileName, const vector< uint8_t > &content)
Set file content.
static void getContent(const string &pathName, const string &fileName, vector< uint8_t > &content)
Get file content.
static void setContentFromStringArray(const string &pathName, const string &fileName, const vector< string > &content)
Set file content as string array.
static void removeFile(const string &pathName, const string &fileName)
Remove file.
static uint64_t getFileSize(const string &pathName, const string &fileName)
Return file size of given file.
static void getContentAsStringArray(const string &pathName, const string &fileName, vector< string > &content)
Get file content as string array.
static const string getFileName(const string &uri)
Get file name.
static bool isPath(const string &uri)
Check if file is a path.
static bool exists(const string &uri)
Check if file exists.
static const string getCurrentWorkingPathName()
Get current working path name.
static const string getContentAsString(const string &pathName, const string &fileName)
Get content as string.
static void rename(const string &fileNameFrom, const string &fileNameTo)
Rename file.
const string & nextToken()
void tokenize(const string &str, const string &delimiters, bool emptyTokens=false)
Tokenize.
std::exception Exception
Exception base class.
File system file name filter interface.
virtual bool accept(const string &path, const string &file)=0
Accept a file.