Estou tentando usar o Directory.GetFiles()
método para recuperar uma lista de arquivos de vários tipos, como mp3
's e jpg
' s. Eu tentei o seguinte sem sorte:
Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);
Existe uma maneira de fazer isso em uma ligação?
c#
filesystems
.net
Jason Z
fonte
fonte
Respostas:
Para .NET 4.0 e posterior,
Para versões anteriores do .NET,
editar: Por favor, leia os comentários. A melhoria sugerida por Paul Farry e o problema de memória / desempenho apontado por Christian.K são ambos muito importantes.
fonte
s.ToLower().Endswith...
s.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
Directory.GetFiles
comDirectory.EnumerateFiles
, msdn.microsoft.com/en-us/library/dd383571.aspx , o que irá evitar os problemas de memória que @ Christian.K menciona.Que tal agora:
Encontrei-o aqui (nos comentários): http://msdn.microsoft.com/en-us/library/wz42302f.aspx
fonte
Parallel.ForEach
para obtê-los em paraleloSe você tiver uma grande lista de extensões para verificar, use o seguinte. Eu não queria criar muitas instruções OR, então modifiquei o que lette escreveu.
fonte
Path.GetExtension
retorna '.ext', não '* .ext' (pelo menos em 3.5+)..abc
, e supportedExtensions, contenha.abcd
. Irá corresponder, embora não deva. Para consertar:supportedExtensions = ".jpg|.abcd|";
com.Contains(Path.GetExtension(s).ToLower() + "|")
. Ou seja, inclua seu caractere separador no teste. IMPORTANTE: seu caractere separador também deve estar após a entrada LAST em supportedExceptions.para
Você poderia:
Directory.EnumerateFiles
para aumentar o desempenho ( qual é a diferença entre Directory.EnumerateFiles e Directory.GetFiles? ).EndsWith("aspx", StringComparison.OrdinalIgnoreCase)
vez de.ToLower().EndsWith("aspx")
)Mas o benefício real
EnumerateFiles
aparece quando você divide os filtros e mescla os resultados:Fica um pouco mais rápido se você não precisar transformá-los em globs (ou seja,
exts = new[] {"*.mp3", "*.jpg"}
já).Avaliação de desempenho com base no seguinte teste do LinqPad (nota:
Perf
apenas repete o delegado 10000 vezes) https://gist.github.com/zaus/7454021(republicado e estendido de 'duplicado', pois essa pergunta não solicitou especificamente LINQ: várias extensões de arquivo searchPattern para System.IO.Directory.GetFiles )
fonte
.FilterFiles(path, "jpg", "gif")
) é melhor que "globs explícitos" (ie.FilterFiles(path, "*.jpg", "*.gif")
).Eu sei que é pergunta antiga, mas LINQ: (.NET40 +)
fonte
file.ToLower()
para combinar facilmente extensões em maiúsculas. E por que não extrair a extensão primeiro, então Regex não tem que examinar caminho inteiro:Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");
Há também uma solução de descida que parece não ter nenhuma sobrecarga de memória ou desempenho e ser bastante elegante:
fonte
Outra maneira de usar o Linq, mas sem precisar retornar tudo e filtrar isso na memória.
Na verdade, são 2 chamadas para
GetFiles()
, mas acho que é consistente com o espírito da pergunta e as retorna em uma enumerável.fonte
Não. Tente o seguinte:
Retirado de: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx
fonte
Deixei
Então
ou
fonte
Não consigo usar o
.Where
método porque estou programando no .NET Framework 2.0 (o Linq é suportado apenas no .NET Framework 3.5+).O código abaixo não diferencia maiúsculas de minúsculas (portanto,
.CaB
ou.cab
também será listado).fonte
A função a seguir pesquisa em vários padrões, separados por vírgulas. Você também pode especificar uma exclusão, por exemplo: "! Web.config" procurará todos os arquivos e excluirá "web.config". Padrões podem ser misturados.
Uso:
fonte
fonte
file.Extension.ToLower()
é uma má prática.String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
no .NET 2.0 (sem Linq):
Então use-o:
fonte
fonte
Acabei de encontrar uma outra maneira de fazê-lo. Ainda não é uma operação, mas joga fora para ver o que as outras pessoas pensam sobre isso.
fonte
A respeito
fonte
Faça as extensões desejadas em uma string, por exemplo, ".mp3.jpg.wma.wmf" e verifique se cada arquivo contém a extensão desejada. Isso funciona com o .net 2.0, pois não usa o LINQ.
A vantagem dessa abordagem é que você pode adicionar ou remover extensões sem editar o código, ou seja, para adicionar imagens png, basta escrever myExtensions = ". Jpg.mp3.png".
fonte
s
fonte
Não ... acredito que você precise fazer quantas chamadas os tipos de arquivo desejados.
Eu mesmo criaria uma função pegando uma matriz em seqüências de caracteres com os ramais necessários e, em seguida, iteraria nessa matriz, fazendo todas as chamadas necessárias. Essa função retornaria uma lista genérica dos arquivos correspondentes às extensões que eu enviei.
Espero que ajude.
fonte
Eu tinha o mesmo problema e não consegui encontrar a solução certa, então escrevi uma função chamada GetFiles:
Esta função chama
Directory.Getfiles()
apenas uma vez.Por exemplo, chame a função assim:
EDIT: Para obter um arquivo com várias extensões, use este:
Por exemplo, chame a função assim:
fonte
Eu me pergunto por que existem tantas "soluções" postadas?
Se meu entendimento de novato sobre como o GetFiles funciona estiver correto, existem apenas duas opções e qualquer uma das soluções acima pode ser resumida a estas:
GetFiles e filtro: Rápido, mas um destruidor de memória devido ao armazenamento de sobrecarga até que os filtros sejam aplicados
Filtrar enquanto GetFiles: mais lento, mais filtros são definidos, mas pouco uso de memória, pois nenhuma sobrecarga é armazenada.
Isso é explicado em uma das postagens acima, com uma referência impressionante: cada opção de filtro causa uma operação GetFile separada, para que a mesma parte do disco rígido seja lida várias vezes.
Na minha opinião, a opção 1) é melhor, mas usar o SearchOption.AllDirectories em pastas como C: \ usaria enormes quantidades de memória.
Portanto, eu faria apenas um sub-método recursivo que percorre todas as subpastas usando a opção 1)
Isso deve causar apenas 1 operação GetFiles em cada pasta e, portanto, ser rápido (Opção 1), mas use apenas uma pequena quantidade de memória, pois os filtros são aplicados após a leitura de cada subpasta -> a sobrecarga é excluída após cada subpasta.
Por favor corrija-me se eu estiver errado. Eu sou como eu disse bastante novo para a programação, mas quero obter uma compreensão mais profunda das coisas para eventualmente se tornar bom nisso :)
fonte
Se você estiver usando o VB.NET (ou importou a dependência para o seu projeto C #), existe realmente um método de conveniência que permite filtrar várias extensões:
No VB.NET, isso pode ser acessado através do namespace My:
Infelizmente, esses métodos de conveniência não suportam uma variante avaliada preguiçosamente, como o
Directory.EnumerateFiles()
fazem.fonte
não sei qual solução é melhor, mas uso isso:
fonte
Aqui está uma maneira simples e elegante de obter arquivos filtrados
fonte
Ou você pode simplesmente converter a sequência de extensões em String ^
fonte
Usar o padrão de pesquisa GetFiles para filtrar a extensão não é seguro! Por exemplo, você tem dois arquivos Test1.xls e Test2.xlsx e deseja filtrar o arquivo xls usando o padrão de pesquisa * .xls, mas GetFiles retorna Test1.xls e Test2.xlsx. Não sabia disso e obtive um erro na produção ambiente quando alguns arquivos temporários foram repentinamente tratados como arquivos corretos. O padrão de pesquisa era * .txt e os arquivos temporários foram nomeados * .txt20181028_100753898 Portanto, o padrão de pesquisa não é confiável, você também deve adicionar uma verificação extra aos nomes de arquivos.
fonte