#include <iostream>
#include <fstream>
#include <list>
#include <pthread.h>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
pthread_mutex_t mtxCerr;
struct var
{
var(fs::path const& pf1, fs::path const& pf2) : pfile1(pf1), pfile2(pf2){};
fs::path pfile1;
fs::path pfile2;
};
void* reverseFile(void* arg)
{
fs::path pfile1(reinterpret_cast<var*>(arg)->pfile1);
fs::path pfile2(reinterpret_cast<var*>(arg)->pfile2);
std::fstream ifs(pfile1, std::ios::in | std::ios::binary), ofs(pfile2, std::ios::out | std::ios::binary);
if (ifs.is_open() && ofs.is_open())
{
ifs.seekg(0, ifs.end);
if (ifs.tellg() >= std::streampos(1))
{
for (ifs.seekg(-1, ifs.cur); ; ifs.seekg(-2, ifs.cur))
{
char c = ifs.get();
//std::cout << int(c) << " ";
ofs.put(c);
if (ifs.tellg() == std::streampos(1))
{
break;
}
}
}
}
else
{
pthread_mutex_lock(&mtxCerr);
std::cerr << "Unable to open file(s): " << pfile1 << " " << pfile2 << "\n\n";
pthread_mutex_unlock(&mtxCerr);
}
ifs.close();
ofs.close();
pthread_exit(0);
}
fs::path newPath(fs::path const& oldPth, fs::path const& pd1, fs::path const& pd2)
{
fs::path ret = pd2;
auto pr = std::mismatch(oldPth.begin(), oldPth.end(), pd1.begin());
for (auto ib(pr.first), ie(oldPth.end()); ib != ie; ++ib)
{
ret /= *ib;
}
return ret;
}
int main()
{
try
{
fs::path pd1("/home/user/student/dir1"); // каталог с исходными файлами
fs::path pd2("/home/user/student/dir2/ddd"); // каталог с инвертированными файлами
pthread_mutex_init(&mtxCerr, nullptr);
if (!fs::exists(pd2))
{
fs::create_directories(pd2); // может кинуть исключение
}
std::list<pthread_t> lt;
std::list<var> la;
for (fs::recursive_directory_iterator ib(pd1), ie; ib != ie; ++ib) // перебираем все файлы в dir 1
{
if (fs::is_regular_file(ib->path())) // инвертируем каждый файл
{
lt.emplace_back();
la.emplace_back(ib->path(), newPath(ib->path(), pd1, pd2));
pthread_create(<.back(), nullptr, reverseFile, &la.back());
}
else if(fs::is_directory(ib->path()))
{
fs::create_directory(newPath(ib->path(), pd1, pd2));
}
}
for(auto& thr : lt)
{
pthread_join(thr, nullptr);
}
pthread_mutex_destroy(&mtxCerr);
}
catch (std::exception const& exc)
{
std::cerr << "Exception: " << exc.what() << std::endl;
}
}