¿Cómo puedo copiar un directorio usando Boost Filesystem? He intentado boost :: filesystem :: copy_directory() pero eso solo crea el directorio de destino y no copia los contenidos.¿Cómo puedo copiar un directorio usando Boost Filesystem
Respuesta
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;
}
Uso:
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)
Por lo que veo, lo peor que puede pasar es que no pasa nada, pero me ganaron ¡Prometo algo! Úselo bajo su propio riesgo.
Tenga en cuenta que el directorio en el que está copiando no debe existir. Si los directorios dentro del directorio que está tratando de copiar no se pueden leer (pensar en la administración de derechos), se omitirán, pero los demás aún se deben copiar.
actualización
refactorizado la función correspondiente a los comentarios. Además, la función ahora devuelve un resultado exitoso. Devolverá false
si no se cumplen los requisitos para los directorios especificados o cualquier directorio dentro del directorio de origen, pero no si no se pudo copiar un solo archivo.
Si usa C++ usted, debería usar 'std :: cerr' en lugar de' fprintf' y 'stderr'. Y también, dado que esto es Boost.Filesystem, debería usar 'boost :: path' en lugar de' std :: string'. –
Gracias por las sugerencias, mejoré la función en consecuencia. – nijansen
Tenga en cuenta que todavía debe tener cuidado con lo que está copiando. Si ejecutó 'copyDir (boost :: filesystem :: path (". "), Boost :: filesystem :: path (" test "))', se copiará hasta que finalice porque la longitud de la ruta excede el límite, o te quedas sin espacio en el disco. – nijansen
Veo esta versión como una versión mejorada de @ nijansen. También admite que los directorios de origen y/o destino sean relativos.
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);
}
}
Las principales diferencias son excepciones en lugar de los valores de retorno, el uso de recursive_directory_iterator
y boost::replace_first
para despojar a la parte constante de la ruta iterador, y confiando en boost::filesystem::copy()
hacer lo correcto con diferentes tipos de archivos (preservando los enlaces simbólicos, por ejemplo).
+1 para preferir excepciones sobre valores de retorno booleanos. Además, relativePathStr se puede calcular utilizando path.lexically_relative (sourceDir), que puede ser más fácil de leer que boost :: replace_first. – Philippe
Ya no necesita impulso para esa tarea ya que su biblioteca del sistema de archivos se ha incluido en C++ std con, p. Ej. la adición de 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.
}
}
Ver también std::filesystem::copy_options
.
Muchas gracias Roi. Espero que los visitantes se den cuenta de su respuesta. – Ant
Tenga en cuenta que esto se agregó a ISO C++ en C++ 17. –
- 1. Cómo usar copy_file en boost :: filesystem?
- 2. Cómo copiar un directorio usando Ant
- 3. Copiar directorio usando Qt
- 4. cómo realizar boost :: filesystem copy_file con sobrescribir
- 5. boost :: filesystem get ruta relativa
- 6. Obtener ruta absoluta con boost :: filesystem :: ruta
- 7. boost filesystem :: path constructor std :: length_error
- 8. ¿Cómo puedo obtener Xcode para vincular y depurar una aplicación con Boost Filesystem?
- 9. ¿Cómo puedo copiar recursivamente los contenidos del directorio usando Perl?
- 10. catching excepción de boost :: filesystem :: is_directory
- 11. ¿Por qué no hay boost :: filesystem :: move_file?
- 12. Cómo copiar varios archivos desde un directorio diferente usando cp?
- 13. Cómo asignar/copiar un Boost :: multi_array
- 14. ¿Cómo comprobar si la ruta es válida en boost :: filesystem?
- 15. ¿Cómo copiar un directorio en un Makefile?
- 16. cómo hacer una copia de boost :: filesystem :: directory_iterator?
- 17. Hadoop Copiar un directorio?
- 18. boost :: filesystem exists() en la ruta del directorio falla, pero is_directory() está bien
- 19. ¿Puedo copiar .git a otro directorio?
- 20. Copie un directorio usando NSIS.
- 21. boost :: filesystem y Unicode en Linux y Windows
- 22. ¿Cómo puedo copiar carpetas usando sftp?
- 23. boost :: ruta relativa del sistema de archivos y directorio actual?
- 24. Hacer un directorio y copiar un archivo
- 25. ¿Cómo puedo copiar un mapa en otro usando std :: copy?
- 26. Copiar Directorio - Post Build Evento
- 27. Iterar todos los archivos en un directorio usando BOOST_FOREACH
- 28. Filesystem filename escape? C#
- 29. Usando os.path de Python, ¿cómo puedo subir un directorio?
- 30. ¿Cómo puedo copiar un directorio de un repositorio git a otro, preservando el historial?
boost :: filesystem :: copy copiará directorios o archivos por igual. Puede escribir un algoritmo recursivo que copie el directorio y los archivos dentro usando eso. – nijansen
Ah. Gracias. Me sorprende que esto no forme parte de boost :: filesystem. Además, no pude encontrar ninguna documentación en el sitio web de la biblioteca de Boost que dijera en inglés qué hace realmente la función copy_directory. – Ant