Jak mogę skopiować katalog przy użyciu systemu plików Boost? Próbowałem boost :: filesystem :: copy_directory(), ale to tylko tworzy docelowy katalog i nie kopiuje zawartości.Jak skopiować katalog przy użyciu systemu plików doładowania?
Odpowiedz
bool copyDir(
boost::filesystem::path const & source,
boost::filesystem::path const & destination
)
{
namespace fs = boost::filesystem;
try
{
// Check whether the function call is valid
if(
!fs::exists(source) ||
!fs::is_directory(source)
)
{
std::cerr << "Source directory " << source.string()
<< " does not exist or is not a directory." << '\n'
;
return false;
}
if(fs::exists(destination))
{
std::cerr << "Destination directory " << destination.string()
<< " already exists." << '\n'
;
return false;
}
// Create the destination directory
if(!fs::create_directory(destination))
{
std::cerr << "Unable to create destination directory"
<< destination.string() << '\n'
;
return false;
}
}
catch(fs::filesystem_error const & e)
{
std::cerr << e.what() << '\n';
return false;
}
// Iterate through the source directory
for(
fs::directory_iterator file(source);
file != fs::directory_iterator(); ++file
)
{
try
{
fs::path current(file->path());
if(fs::is_directory(current))
{
// Found directory: Recursion
if(
!copyDir(
current,
destination/current.filename()
)
)
{
return false;
}
}
else
{
// Found file: Copy
fs::copy_file(
current,
destination/current.filename()
);
}
}
catch(fs::filesystem_error const & e)
{
std:: cerr << e.what() << '\n';
}
}
return true;
}
Zastosowanie:
copyDir(boost::filesystem::path("/home/nijansen/test"), boost::filesystem::path("/home/nijansen/test_copy"));
(Unix)
copyDir(boost::filesystem::path("C:\\Users\\nijansen\\test"), boost::filesystem::path("C:\\Users\\nijansen\\test2"));
(Windows)
O ile widzę, to najgorsze co może się zdarzyć, że nic się nie dzieje, ale wygrał Nic nie obiecuję! Używaj na własne ryzyko.
Należy pamiętać, że katalog, do którego kopiujesz, nie może istnieć. Jeśli katalogi w katalogu, który próbujesz skopiować, nie mogą zostać odczytane (pomyśl o zarządzaniu uprawnieniami), zostaną one pominięte, ale pozostałe powinny zostać skopiowane.
Aktualizacja
refactored funkcję odpowiednią do komentarzy. Ponadto funkcja zwraca teraz wynik pomyślny. Zwróci ona false
, jeśli wymagania dla podanych katalogów lub katalogów w katalogu źródłowym nie są spełnione, ale nie w przypadku, gdy nie można skopiować pojedynczego pliku.
Jeśli używasz C++, powinieneś użyć 'std :: cerr' zamiast' fprintf' i 'stderr'. A także, ponieważ jest to Boost.Filesystem, powinieneś użyć 'boost :: path' zamiast' std :: string'. –
Dzięki za sugestie, poprawiłem funkcję odpowiednio. – nijansen
Pamiętaj, że musisz uważać na to, co kopiujesz. Jeśli uruchomiłeś 'copyDir (boost :: filesystem :: path (". "), Boost :: filesystem :: path (" test "))', kopiuje się do momentu zakończenia, ponieważ długość ścieżki przekracza limit, lub skończy Ci się miejsce na dysku. – nijansen
Widzę tę wersję jako ulepszoną po wersji odpowiedzi @ nijansen. Wspiera także katalogi źródłowe i/lub docelowe, które mają być względne.
namespace fs = boost::filesystem;
void copyDirectoryRecursively(const fs::path& sourceDir, const fs::path& destinationDir)
{
if (!fs::exists(sourceDir) || !fs::is_directory(sourceDir))
{
throw std::runtime_error("Source directory " + sourceDir.string() + " does not exist or is not a directory");
}
if (fs::exists(destinationDir))
{
throw std::runtime_error("Destination directory " + destinationDir.string() + " already exists");
}
if (!fs::create_directory(destinationDir))
{
throw std::runtime_error("Cannot create destination directory " + destinationDir.string());
}
for (const auto& dirEnt : fs::recursive_directory_iterator{sourceDir})
{
const auto& path = dirEnt.path();
auto relativePathStr = path.string();
boost::replace_first(relativePathStr, sourceDir.string(), "");
fs::copy(path, destinationDir/relativePathStr);
}
}
Główne różnice są wyjątki zamiast wartości zwracanej, stosowanie recursive_directory_iterator
i boost::replace_first
rozebrać wspólną część ścieżki iteratora, a opierając się na boost::filesystem::copy()
aby zrobić dobry uczynek z różnych typów plików (zachowując dowiązania, na przykład).
+1 dla preferowania wyjątków w porównaniu z wartościami zwracanymi przez boolowskie. Również relativePathStr można obliczyć za pomocą path.lexically_relative (sourceDir), który może być łatwiejszy do odczytania niż boost :: replace_first. – Philippe
Już nie potrzebujesz doładowania dla tego zadania, ponieważ jego biblioteka systemów plików została dołączona do std C++ z np. dodanie std::filesystem::copy
#include <exception>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
fs::path source = "path/to/source/folder";
fs::path target = "path/to/target/folder";
try {
fs::copy(source, target, fs::copy_options::recursive);
}
catch (std::exception& e) { // Not using fs::filesystem_error since std::bad_alloc can throw too.
// Handle exception or use error code overload of fs::copy.
}
}
Zobacz także std::filesystem::copy_options
.
Wielkie dzięki Roi. Mam nadzieję, że odwiedzający zauważą twoją odpowiedź. – Ant
Należy zauważyć, że dodano to do ISO C++ w C++ 17. –
- 1. Hadoop skopiować katalog?
- 2. Aktualizowanie pliku XML przy użyciu doładowania property_tree
- 3. Utwórz katalog przy użyciu Nant
- 4. Jak mogę skopiować pliki do systemu plików Androida?
- 5. Rozwiązuj dowiązania symboliczne z systemem plików doładowania
- 6. TeamCity - Jak mogę skopiować katalog główny VCS?
- 7. Kopiowanie katalogu przy użyciu Qt
- 8. Jak skopiować cały katalog w generatorze Railsów z szablonów
- 9. Jak utworzyć plik z systemem plików doładowania bez jego otwierania?
- 10. Jak skopiować katalog za pomocą zadania Kopiuj w gradle
- 11. jak skopiować dane z pliku do PostgreSQL przy użyciu JDBC?
- 12. Jak skopiować rodzajowe kolekcji w Javie przy użyciu symboli wieloznacznych
- 13. Jak skopiować obraz PNG do schowka przy użyciu Delphi
- 14. Jak skopiować i wkleić węzeł SVG przy użyciu jQuery
- 15. Kopiowanie dużych plików przy użyciu pulpitu zdalnego
- 16. Jak skopiować textField do schowka systemu OSX?
- 17. Katalog początkowy plików wsadowych systemu Windows po uruchomieniu "admin as
- 18. Wyodrębnianie submatów przy użyciu regex doładowania w języku C++
- 19. Jaki jest sposób, aby skopiować katalog
- 20. użyciu from_string z datą doładowania
- 21. Budowanie podzbioru bibliotek doładowania
- 22. Przesyłanie plików przy użyciu Vapor
- 23. Instalowanie dodatkowych plików przy użyciu CMake
- 24. Jak zmienić bieżący katalog roboczy przy użyciu pliku wsadowego
- 25. jak zmienić katalog przy użyciu wiersza poleceń Windows
- 26. Jak uzyskać bieżący katalog roboczy przy użyciu Pythona 3?
- 27. Jak sprawdzić, czy katalog istnieje przy użyciu C++ i WinAPI
- 28. Base64 zakodować rzut użyciu doładowania wyjątek
- 29. Ciąg połączenia przy użyciu uwierzytelniania systemu Windows
- 30. Jak skopiować katalog z lokalnego komputera do zdalnego komputera
boost :: filesystem :: copy spowoduje skopiowanie katalogów lub plików. Możesz napisać rekursywny algorytm, który skopiuje katalog i pliki w jego obrębie. – nijansen
Ah. Dziękuję Ci. Jestem zaskoczony, że nie jest to częścią systemu boost :: files. Również nie znalazłem żadnej dokumentacji na stronie internetowej biblioteki Boost, która mówi po angielsku, co właściwie robi funkcja copy_directory. – Ant