I am using below code to copy files, directories, soft links, hard links from one directory to another.
#include <fstream>
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
//function copy files
void cpFile(const fs::path & srcPath,
const fs::path & dstPath) {
std::ifstream srcFile(srcPath, std::ios::binary);
std::ofstream dstFile(dstPath, std::ios::binary);
if (!srcFile || !dstFile) {
std::cout << "Failed to get the file." << std::endl;
return;
}
dstFile << srcFile.rdbuf();
srcFile.close();
dstFile.close();
}
//function create new directory
void cpDirectory(const fs::path & srcPath,
const fs::path & dstPath) {
fs::create_directories(dstPath);
for (const auto & entry: fs::directory_iterator(srcPath)) {
const fs::path & srcFilePath = entry.path();
const fs::path & dstFilePath = dstPath / srcFilePath.filename();
//if directory then create new folder
if (fs::is_directory(srcFilePath)) {
cpDirectory(srcFilePath, dstFilePath);
} else {
cpFile(srcFilePath, dstFilePath);
}
}
}
int main(int argc, char *argv[]) {
const auto root = fs::current_path();
const fs::path srcPath = argv[1];
const fs::path dstPath = argv[2];
// Copy only those files which contain "Sub" in their stem.
cpDirectory(srcPath, dstPath);
return 0;
}
Below is content of src directory:
$ ls -ltr a/
total 4
-rw-rw-r-- 1 ubuntu ubuntu 0 Sep 30 19:58 test.txt
-rw-rw-r-- 1 ubuntu ubuntu 0 Oct 1 18:12 d.txt
lrwxrwxrwx 1 root root 5 Oct 1 18:12 linkd -> d.txt
drwxrwxr-x 2 ubuntu ubuntu 4096 Oct 1 18:21 testd
When i run the code:
$ ./copyRec a/ e/
Below is the content of dst directory:
$ls -ltr e/
total 4
drwxrwxr-x 2 ubuntu ubuntu 4096 Oct 1 18:21 testd
-rw-rw-r-- 1 ubuntu ubuntu 0 Oct 1 18:38 test.txt
-rw-rw-r-- 1 ubuntu ubuntu 0 Oct 1 18:38 linkd
-rw-rw-r-- 1 ubuntu ubuntu 0 Oct 1 18:38 d.txt
Where linkd is a soft link to d.txt but it is not preserved and is shown as a regular file. Please help.
You must take specific action in order to preserve symbolic links. The filesystem library will not do it for you.
You already know how to use
is_directory. If you go back and look at your C++ reference or textbook where you learned aboutis_directory, you will also find a description ofis_symlinkwhich checks whether the given entry is a symbolic link.Then, you will need to use
read_symlinkto read the symlink, andcreate_symlinkto recreate it.