Quero copiar todo o conteúdo de um diretório de um local para outro em C #.
Não parece haver uma maneira de fazer isso usando System.IO
classes sem muita recursão.
Existe um método no VB que podemos usar se adicionarmos uma referência a Microsoft.VisualBasic
:
new Microsoft.VisualBasic.Devices.Computer().
FileSystem.CopyDirectory( sourceFolder, outputFolder );
Parece um truque feio. Existe uma maneira melhor?
Microsoft.VisualBasic
e nãoSystem.IO
? A razão pela qual não está no Mono é porque todas as bibliotecas consideradas 'essenciais' sãoSystem.[something]
- todas as outras não são. Não tenho nenhum problema ao referenciar uma DLL extra, mas há uma boa razão pela qual a Microsoft não incluiu esse recursoSystem.IO
.Respostas:
Muito facil
fonte
Replace
tem um problema se você tem um padrão de repetição dentro do caminho, por exemplo"sourceDir/things/sourceDir/things"
deve tornar-se"destinationDir/things/sourceDir/things"
, mas se você usar substituí-lo torna-se"destinationDir/things/destinationDir/things"
*.*
invés de*
? Você também não deseja copiar arquivos sem extensões?Hmm, acho que não entendi a pergunta, mas vou arriscar. O que há de errado com o seguinte método direto?
EDITAR Como esta postagem recebeu um número impressionante de votos negativos por uma resposta tão simples a uma pergunta igualmente simples, deixe-me acrescentar uma explicação. Por favor, leia isso antes da votação .
Primeiro de tudo, esse código não pretende ser um substituto para o código da pergunta. É apenas para fins ilustrativos.
Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectory
faz alguns testes adicionais de correção (por exemplo, se a origem e o destino são diretórios válidos, se a origem é um pai do destino, etc.) que estão faltando nesta resposta. Esse código provavelmente também é mais otimizado.Dito isto, o código funciona bem . Ele tem (quase idêntica) foi usado em um software maduro durante anos. Além da inconstância inerente presente em todos os manipuladores de E / S (por exemplo, o que acontece se o usuário desconectar manualmente a unidade USB enquanto seu código estiver gravando nela?), Não há problemas conhecidos.
Em particular, gostaria de salientar que o uso da recursão aqui não é absolutamente um problema. Nem na teoria (conceitualmente, é a solução mais elegante) nem na prática: esse código não sobrecarregará a pilha . A pilha é grande o suficiente para lidar com hierarquias de arquivos aninhadas profundamente. Muito antes de o espaço da pilha se tornar um problema, a limitação de comprimento do caminho da pasta entra em ação.
Observe que um usuário mal - intencionado pode quebrar essa suposição usando diretórios profundamente aninhados de uma letra cada. Eu não tentei isso. Mas apenas para ilustrar o ponto: para fazer esse código transbordar em um computador típico, os diretórios precisariam ser aninhados alguns milhares de vezes. Este simplesmente não é um cenário realista.
fonte
Copiado do MSDN :
fonte
Tente o seguinte:
Seus argumentos xcopy podem variar, mas você entendeu.
fonte
Ou, se desejar seguir o caminho mais difícil, adicione uma referência ao seu projeto para Microsoft.VisualBasic e use o seguinte:
No entanto, o uso de uma das funções recursivas é o melhor caminho a percorrer, pois não será necessário carregar a DLL do VB.
fonte
System.IO.Directory
, mas é melhor do que reescrevê-lo!Este site sempre me ajudou muito, e agora é minha vez de ajudar os outros com o que eu sei.
Espero que meu código abaixo seja útil para alguém.
fonte
Path.Combine()
. Nunca use concatenação de cadeias para montar caminhos de arquivo.source_dir.Length + 1
, nãosource_dir.Length
.Copie a pasta recursivamente sem recursão para evitar o estouro da pilha.
fonte
Aqui está uma classe de utilitário que eu usei para tarefas de E / S como esta.
fonte
Pode não ser sensível ao desempenho, mas estou usando-o para pastas de 30 MB e funciona perfeitamente. Além disso, eu não gostei de toda a quantidade de código e recursão necessária para uma tarefa tão fácil.
Nota: ZipFile está disponível no .NET 4.5+ no espaço para nome System.IO.Compression
fonte
Uma pequena melhoria na resposta do d4nt, pois você provavelmente deseja verificar se há erros e não precisa alterar os caminhos do xcopy se estiver trabalhando em um servidor e uma máquina de desenvolvimento:
fonte
Este é o meu código espero que isso ajude
fonte
SearchOption
sinalizador nas pesquisas de pastas e arquivos, ele faz isso em 4 linhas de código. Verifique também a.HasFlag
extensão agora em enums.Se você gosta da resposta popular do Konrad, mas deseja que
source
ela seja uma pastatarget
, em vez de colocar seus filhos natarget
pasta, aqui está o código para isso. Ele retorna o recém-criadoDirectoryInfo
, o que é útil:fonte
Você sempre pode usar isso , retirado do site da Microsofts.
fonte
file.CopyTo(temppath, false);
diz "copie este arquivo para este local, apenas se ele não existir", que na maioria das vezes não é o que queremos. Mas, eu posso entender por que o padrão é isso. Talvez adicione um sinalizador ao método para substituir arquivos.tboswell substitui a versão Proof (que é resiliente à repetição do padrão no caminho do arquivo)
fonte
Path.Combine()
. Nunca use concatenação de cadeias para montar caminhos de arquivo.Minha solução é basicamente uma modificação da resposta do @ Termininja, no entanto eu a aprimorei um pouco e parece ser mais de 5 vezes mais rápida que a resposta aceita.
Edição: Modificar @Ahmed Sabry para foreach paralelo completo produz um resultado melhor, no entanto, o código usa a função recursiva e não é ideal em algumas situações.
fonte
Desculpe pelo código anterior, ele ainda tinha bugs :( (foi vítima do problema mais rápido da arma). Aqui ele é testado e está funcionando. A chave é o SearchOption.AllDirectories, que elimina a necessidade de recursão explícita.
fonte
Aqui está um método de extensão para DirectoryInfo no FileInfo.CopyTo (observe o
overwrite
parâmetro):fonte
Use essa classe.
fonte
.ToList().ForEach(
(que é um pouco mais de trabalho, memória e um pouco mais lenta do que apenas enumerar os diretórios diretamente) e como um método de extensão. A resposta selecionada usaSearchOption.AllDirectories
e evita recursão, portanto, recomendo mudar para esse modelo. Além disso, você geralmente não precisa do nome do tipo em métodos de extensão - eu renomeá-lo paraCopyTo()
modo que se tornousourceDir.CopyTo(destination);
Uma variante com apenas um loop para copiar todas as pastas e arquivos:
fonte
Regex
, provavelmente também deve fazerRegex.Escape(path)
parte da composição da sua expressão (especialmente considerando o separador de caminho do Windows). Você também pode se beneficiar da criação (e talvez compilação) de umnew Regex()
objeto fora do loop, em vez de confiar no método estático.Melhor que qualquer código (método de extensão para DirectoryInfo com recursão)
fonte
Copie e substitua todos os arquivos da pasta
fonte
try
catch
throw
é inútil.O código abaixo é um exemplo de como copiar diretórios da Microsoft e é compartilhado pelo querido @iato, mas apenas copia subdiretórios e arquivos da pasta de origem recursivamente e não copia a pasta de origem por si próprio (como clique com o botão direito do mouse -> copiar )
mas há uma maneira complicada abaixo desta resposta:
Se você deseja copiar o conteúdo da pasta e subpastas de origem recursivamente, basta usá-lo da seguinte maneira:
mas se você deseja copiar o diretório de origem por si próprio (semelhante ao clique com o botão direito do mouse na pasta de origem e ao clicar em copiar, na pasta de destino em que você clicou em colar), use o seguinte:
fonte