CSharp (C#) – Como ordenar arquivos retornados pela DirectoryInfo.GetFiles utilizando Natural Sort

Visualizações: 294
Tempo de Leitura: 4 minutos

Olá pessoal,
Bom dia!

Neste post vou fazer uma abordagem bem simples sobre algo que muitos desenvolvedores .NET buscam na internet, como eu mesmo busquei essa solução, mas que é um pouco complicado de encontrar, pois a maioria das soluções postadas não funciona.

O meu problema era que eu utilizo muito uma função C# no meu CLR para listar arquivos de um diretório (Já havia postado essa função no post SQL Server – Como listar, ler, escrever, copiar, excluir e mover arquivos com o CLR (C#)), mas o fato dos arquivos não serem ordenados da forma correta sempre me incomodou, e eu resolvi melhorar isso.

Exemplo do uso atual:
CSharp sort sorting DirectoryInfo.GetFiles by name natural sort 1

Mesmo que você utilize uma cláusula ORDER BY para tentar ordenar, isso não vai funcionar, porque o SQL Server irá fazer a ordenação de strings utilização a ordenação alfanumérica.

Como funciona o algoritmo de ordenação de strings alfanuméricas
Esse tipo de algoritmo utiliza o código ASCII para ordenar os dados, comparando caractere por caractere até terminar a string ou o código ASCII de uma string for menor que o da outra. Desta forma, numa comparação entre Arquivo 100 e Arquivo 20, a comparação será feita da seguinte forma:

  • Cada caractere da palavra “Arquivo” será comparada entre as 2 strings. Como elas são iguais, o algoritmo irá prosseguir para o restante da string
  • O caractere “1” será comparado com o caractere “2”. Como ele é menor, a ordenação termina aí, colocando “Arquivo 100” antes de “Arquivo 20”

Como funciona o algoritmo de ordenação de strings Natural Sort
Assim como eu me incomodo com essa ordenação, que é a padrão pela grande maioria das linguagens de programação, muita gente também não gosta do “100” vir antes do “2000” e por para dar uma visão mais “humanizada”, foi-se criado o algoritmo de Natural Sort, que separa caracteres numéricos de letras, e os ordena separadamente. Os números são comparados de forma numérica (onde 100 é maior que 20), e as strings ele continua utilizando o código ASCII.

Para implementar o algoritmo Natural Sort, encontrei um código no blog do James McCormack para criar uma classe ICompare no C# e assim, ordenar os meus arquivos na minha função (e qualquer outra lista de arquivos que você precisar ordenar).

Visualizar Código-fonte da classe ICompare

Agora eu preciso alterar a minha função de listar arquivos (também incluí uma flag booleana para listar arquivos dentro de subdiretórios ou não) e incluir uma função de OrderBy através da biblioteca LINQ.

Neste trecho:

Eu alterei para esse trecho:

E com isso, o nosso problema foi resolvido, onde temos o seguinte resultado:
CSharp sort sorting DirectoryInfo.GetFiles by name natural sort solved

Visualizar Código-fonte completo dessa função

Muito obrigado pela visita e até o próximo post!