Common/FileUtil: Add Move() function.

This commit is contained in:
Admiral H. Curtiss 2023-02-24 21:39:02 +01:00
parent 1ed0e014cd
commit 5367bf394c
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
2 changed files with 59 additions and 0 deletions

View File

@ -558,6 +558,58 @@ bool Copy(std::string_view source_path, std::string_view dest_path, bool overwri
return true;
}
static bool MoveWithOverwrite(const std::filesystem::path& src, const std::filesystem::path& dst,
std::error_code& error)
{
fs::rename(src, dst, error);
if (!error)
return true;
// rename failed, try fallbacks
if (!fs::is_directory(src))
{
// src is not a directory (ie, probably a file), try to copy file + delete
if (!fs::copy_file(src, dst, fs::copy_options::overwrite_existing, error))
return false;
if (!fs::remove(src, error))
return false;
return true;
}
// src is a directory, recurse into it and try to move all sub-elements one by one
// this usually happens because the target is a non-empty directory
for (fs::directory_iterator it(src, error); it != fs::directory_iterator(); it.increment(error))
{
if (error)
return false;
if (!MoveWithOverwrite(it->path(), dst / it->path().filename(), error))
return false;
}
if (error)
return false;
// all sub-elements moved, remove top directory
if (!fs::remove(src, error))
return false;
return true;
}
bool MoveWithOverwrite(std::string_view source_path, std::string_view dest_path)
{
DEBUG_LOG_FMT(COMMON, "{}: {} --> {}", __func__, source_path, dest_path);
auto src_path = StringToPath(source_path);
auto dst_path = StringToPath(dest_path);
std::error_code error;
if (!MoveWithOverwrite(src_path, dst_path, error))
{
ERROR_LOG_FMT(COMMON, "{}: failed {} --> {}: {}", __func__, source_path, dest_path,
error.message());
}
return true;
}
// Create directory and copy contents (optionally overwrites existing files)
bool CopyDir(const std::string& source_path, const std::string& dest_path, const bool destructive)
{

View File

@ -193,6 +193,13 @@ std::string GetCurrentDir();
bool Copy(std::string_view source_path, std::string_view dest_path,
bool overwrite_existing = false);
// Moves source_path to dest_path. On success, the source_path will no longer exist, and the
// dest_path will contain the data previously in source_path. Files in dest_path will be overwritten
// if they match files in source_path, but files that only exist in dest_path will be kept. No
// guarantee on the state is given on failure; the move may have completely failed or partially
// completed.
bool MoveWithOverwrite(std::string_view source_path, std::string_view dest_path);
// Create directory and copy contents (optionally overwrites existing files)
bool CopyDir(const std::string& source_path, const std::string& dest_path,
bool destructive = false);