Quiero copiar todo el contenido de un directorio de una ubicación a otra en C #.
No parece haber una manera de hacer esto usando System.IO
clases sin mucha recursividad.
Hay un método en VB que podemos usar si agregamos una referencia a Microsoft.VisualBasic
:
new Microsoft.VisualBasic.Devices.Computer().
FileSystem.CopyDirectory( sourceFolder, outputFolder );
Esto parece un truco bastante feo. ¿Hay una mejor manera?
Microsoft.VisualBasic
y noSystem.IO
? La razón por la que no está en Mono es porque todas las bibliotecas que se consideran 'núcleo' sonSystem.[something]
, todas las demás no lo son. No tengo ningún problema para hacer referencia a una DLL adicional, pero hay una buena razón por la cual Microsoft no ha incluido esta funciónSystem.IO
.Respuestas:
Más fácil
fuente
Replace
tiene un problema si usted tiene un patrón que se repite dentro de la ruta, por ejemplo,"sourceDir/things/sourceDir/things"
debería ser"destinationDir/things/sourceDir/things"
, pero si se utiliza reemplazarlo se convierte en"destinationDir/things/destinationDir/things"
*.*
lugar de*
? ¿No quieres copiar archivos sin extensiones también?Hmm, creo que no he entendido bien la pregunta, pero voy a arriesgarme. ¿Qué tiene de malo el siguiente método sencillo?
EDITAR Dado que esta publicación ha cosechado una cantidad impresionante de votos negativos para una respuesta tan simple a una pregunta igualmente simple, permítanme agregar una explicación. Por favor lea esto antes de votar abajo .
En primer lugar, este código no se incluye como un reemplazo directo del código en la pregunta. Es solo para fines ilustrativos.
Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectory
realiza algunas pruebas de corrección adicionales (por ejemplo, si el origen y el destino son directorios válidos, si el origen es un padre del destino, etc.) que faltan en esta respuesta. Ese código probablemente también esté más optimizado.Dicho esto, el código funciona bien . Se ha utilizado (casi idénticamente) en un software maduro durante años. Además de la inconstancia inherente presente con todos los manejos de E / S (por ejemplo, ¿qué sucede si el usuario desconecta manualmente la unidad USB mientras su código está escribiendo en ella?), No hay problemas conocidos.
En particular, me gustaría señalar que el uso de la recursividad aquí no es absolutamente un problema. Ni en teoría (conceptualmente, es la solución más elegante) ni en la práctica: este código no desbordará la pila . La pila es lo suficientemente grande como para manejar incluso jerarquías de archivos profundamente anidadas. Mucho antes de que el espacio de pila se convierta en un problema, la limitación de longitud de la ruta de la carpeta entra en juego.
Tenga en cuenta que un usuario malintencionado podría romper esta suposición utilizando directorios profundamente anidados de una letra cada uno. No he intentado esto. Pero solo para ilustrar el punto: para que este código se desborde en una computadora típica, los directorios tendrían que anidarse unos miles de veces. Esto simplemente no es un escenario realista.
fuente
Copiado de MSDN :
fuente
Prueba esto:
Sus argumentos de xcopy pueden variar, pero se entiende la idea.
fuente
O, si desea ir por el camino difícil, agregue una referencia a su proyecto para Microsoft.VisualBasic y luego use lo siguiente:
Sin embargo, usar una de las funciones recursivas es una mejor manera de hacerlo, ya que no tendrá que cargar el dll de VB.
fuente
System.IO.Directory
, ¡pero es mejor que reescribirlo!Este sitio siempre me ha ayudado mucho y ahora es mi turno de ayudar a los demás con lo que sé.
Espero que mi siguiente código sea útil para alguien.
fuente
Path.Combine()
. Nunca use la concatenación de cadenas para juntar rutas de archivos.source_dir.Length + 1
, nosource_dir.Length
.Copie la carpeta de forma recursiva sin recurrencia para evitar el desbordamiento de la pila.
fuente
Aquí hay una clase de utilidad que he usado para tareas de IO como esta.
fuente
Puede que no tenga en cuenta el rendimiento, pero lo estoy usando para carpetas de 30 MB y funciona perfectamente. Además, no me gustó toda la cantidad de código y recursión requerida para una tarea tan fácil.
Nota: ZipFile está disponible en .NET 4.5+ en el espacio de nombres System.IO.Compression
fuente
Una mejora menor en la respuesta de d4nt, ya que probablemente desee verificar los errores y no tener que cambiar las rutas de xcopy si está trabajando en un servidor y una máquina de desarrollo:
fuente
Este es mi código espero esta ayuda
fuente
SearchOption
bandera en las búsquedas de carpetas y archivos, lo hace en 4 líneas de código. Consulte también la.HasFlag
extensión ahora en enumeraciones.Si te gusta la respuesta popular de Konrad, pero quieres
source
que sea una carpeta debajotarget
, en lugar de poner a sus hijos debajo de latarget
carpeta, aquí está el código para eso. Devuelve el recién creadoDirectoryInfo
, que es útil:fuente
Siempre puede usar esto , tomado del sitio web de Microsofts.
fuente
file.CopyTo(temppath, false);
dice "copie este archivo a este lugar, solo si no existe", que la mayoría de las veces no es lo que queremos. Pero, puedo entender por qué lo predeterminado es eso. Tal vez agregue una bandera al método para sobrescribir archivos.Versión de prueba de reemplazo de tboswell (que es resistente a la repetición de patrones en filepath)
fuente
Path.Combine()
. Nunca use la concatenación de cadenas para juntar rutas de archivos.Mi solución es básicamente una modificación de la respuesta de @ Termininja, sin embargo, la he mejorado un poco y parece ser más de 5 veces más rápida que la respuesta aceptada.
EDITAR: Modificar @Ahmed Sabry a foreach paralelo completo produce un mejor resultado, sin embargo, el código usa la función recursiva y no es ideal en alguna situación.
fuente
Perdón por el código anterior, todavía tenía errores :( (cayó presa del problema de arma más rápido). Aquí está probado y funciona. La clave es SearchOption.AllDirectories, que elimina la necesidad de recurrencia explícita.
fuente
Aquí hay un método de extensión para DirectoryInfo a la FileInfo.CopyTo (tenga en cuenta el
overwrite
parámetro):fuente
Usa esta clase.
fuente
.ToList().ForEach(
(que es un poco más trabajo, memoria y un poco más lento que simplemente enumerar los directorios directamente) y como un método de extensión. La respuesta seleccionada usaSearchOption.AllDirectories
y evita la recurrencia, por lo que recomendaría cambiar a ese modelo. Además, por lo general, no es necesario el nombre del tipo en los métodos de extensión - Me cambiarle el nombre aCopyTo()
fin de que se hizosourceDir.CopyTo(destination);
Una variante con un solo bucle para copiar todas las carpetas y archivos:
fuente
Regex
, probablemente también deberíaRegex.Escape(path)
formar parte de su composición de expresión (especialmente teniendo en cuenta el separador de ruta de Windows). También puede obtener beneficios al crear (y tal vez compilar) unnew Regex()
objeto fuera del ciclo, en lugar de depender del método estático.Mejor que cualquier código (método de extensión a DirectoryInfo con recursividad)
fuente
Copie y reemplace todos los archivos de la carpeta
fuente
try
catch
throw
tiene sentido.El siguiente código es una sugerencia de Microsoft sobre cómo copiar directorios y lo comparte querido @iato, pero solo copia subdirectorios y archivos de la carpeta de origen de forma recursiva y no copia la carpeta de origen. (como hacer clic con el botón derecho -> copiar )
pero hay una forma complicada debajo de esta respuesta:
Si desea copiar el contenido de la carpeta de origen y las subcarpetas de forma recursiva, simplemente puede usarlo así:
pero si desea copiar el directorio de origen por sí mismo (de forma similar a como hizo clic derecho en la carpeta de origen y luego hizo clic en copiar y luego en la carpeta de destino en la que hizo clic en pegar), debe usar así:
fuente