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

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!

SQL, sql server, sql server 2008, sql server 2008 R2, Oracle, Oracle Database, Oracle 11g, Oracle 10g, Oracle 12c, MySQL, Firebird, Consultoria, Consultor, Programador, Programação. Desenvolvedor, Analista de Sistemas, DBA, Criação de website, Criação de Sistema Web, Vitória, Vila Velha, Guarapari, Espírito Santo, ES, Consultoria SQL em VItória, Treinamento, Curso, Prestação de serviço, prestar serviço, freelancer, freela, banco de dados, consultoria em banco de dados, consultor de banco de dados

Deixe uma resposta