PhotoOrganizer – Brincando com Diretórios e Arquivos através do System.IO

Pessoal, bom dia

Uma coisa boa de quem sabe programar, ou quer aprender, é sempre poder criar ferramentas para resolver os seus problemas sem ter de recorrer a programas da internet que por vezes não funcionam, carregam vírus e trojans ou não servem totalmente a nossa necessidade.

Pensando nisto surgiu a minha problemática:
Eu e minha esposa mantemos um Ateliê de Artes e Artigos de festa infantis (https://www.facebook.com/AtelieFlordePapel) eu sou o responsável por realizar todas as artes e para isto preciso salvar muitas imagens da internet. Um belo dia meu HD do notebook já estava quase cheio e verifiquei que eu tinha muitos arquivos repetidos, surgiu a ideia, vou criar uma aplicação para MOVER meus arquivos repetidos para um diretório a parte e de lá eu analiso e excluo eles.

A ideia é interessante, criei o Projeto PhotoOrganizer no #VS2013, porém, por que criar uma código que só funciona com foto, vamos fazer de forma que aceite qualquer tipo de arquivo.

Agora, vamos estudar a forma de comparação:

  1. Realizar a comparação através de nome dos arquivos: Não dá certo, A comparação que quero fazer é de conteúdo, nome não me diz nada.
  2. Comparar o Conteúdo do arquivo: Através da analise dos binários do arquivo eu consigo saber se eles são iguais, porém, é uma varredura um pouco mais lenta dependendo do tamanho do arquivo, precisamos criar uma verificação preliminar
  3. Comparar o Tamanho dos arquivos: Opa, agora sim…verifico se os arquivos tem o mesmo tamanho, se tiverem já é um possível sinal que são iguais, e trata-se de uma comparação bem mais rápida de ser feita. Caso eles tenham o mesmo tamanho eu passo para a comparação dos binário

Vamos agora programar:

O interessante deste projeto é que vamos estudar as classes e métodos do Namespace System.IO, biblioteca responsável por permitir trabalhar com arquivos físicos ou em memória, diretórios de arquivos…lendo, criando e apagando.

Para carregar um arquivo em memória no C# devemos instanciar a classe FileInfo, conforme exemplo:

FileInfo Finfo = new FileInfo("C:\\Temp\\Arquivo.jpg");

Através dela podemos, ler, deletar, mover, copiar um arquivo

Para carregar um diretório em memória, e capturar o arquivos que nele contém, utilizamos a classe DirectoryInfo, conforme exemplo:

DirectoryInfo dInfo = new DirectoryInfo("c:\\temp");
foreach (FileInfo fInfo in dInfo.GetFiles("*.jpg"))
{
// Faz alguma coisa com o arquivo
}

com isto montamos dois métodos principais, sendo o primeiro o responsável por comparar o tamanho dos arquivos:


private bool validaPorTamanho(FileInfo fInfoComparador, FileInfo fInfoComparado)
{
return fInfoComparador.Length.Equals(fInfoComparado.Length);
}

O segundo método é o principal , responsável por comparar os arquivos através do seu array de bytes


private bool validaPorConteudo(FileInfo afInfoComparador, FileInfo afInfoComparado)
{
// Indicador booleano de igualdade dos arquivos
bool abolArquivosIguais = true;

// Instância do Arquivo original

StreamReader lstremArquivoComparador = null;

// Instância do Arquivo a ser comparado

StreamReader lstremArquivoComparado = null;

// Array de Bytes do arquivo oringal

byte[] larrArquivoComparador = null;

// Array de Bytes do arquivo comparado

byte[] larrArquivoComparado = null;

try
{
//  Carrega os arquivos nas streams

lstremArquivoComparador = new StreamReader(afInfoComparador.FullName);

lstremArquivoComparado = new StreamReader(afInfoComparado.FullName);

/*Verifica se as stream não estão vázias
(pode acontecer caso o arquivo já tenha sido deletado)*/

if (lstremArquivoComparador != null && lstremArquivoComparado != null)
{
// Carrega os arrays de bytes
larrArquivoComparador = new byte[(int)lstremArquivoComparador.BaseStream.Length];
lstremArquivoComparador.BaseStream.Read(larrArquivoComparador, 0, (int)lstremArquivoComparador.BaseStream.Length);

larrArquivoComparado = new byte[(int)lstremArquivoComparado.BaseStream.Length];
lstremArquivoComparado.BaseStream.Read(larrArquivoComparado, 0, (int)lstremArquivoComparado.BaseStream.Length);

// Verifica novamente se os arrays tem o mesmo tamanho
if (larrArquivoComparador.Length == larrArquivoComparado.Length)
{
abolArquivosIguais = true;

// Realiza a comparação lendo binário a binário dos arquivos
for (int i = 0; i < larrArquivoComparador.Length; i++)
{
if (larrArquivoComparador[i] != larrArquivoComparado[i])
abolArquivosIguais = false;
}
}
else
{
abolArquivosIguais = false;
}
}
else { abolArquivosIguais = false; }
}
catch (Exception)
{
}
finally
{
// Ao final da execução, libera os arquivos
if (lstremArquivoComparador != null)
lstremArquivoComparador.Dispose();

if (lstremArquivoComparado != null)
lstremArquivoComparado.Dispose();
}
return abolArquivosIguais;
}

e agora vamos criar o método que sequenciar as comparações:


private bool comparaArquivos(FileInfo afInfoComparador, FileInfo afInfoComparado)
{
bool abolArquivosIguais = false;
abolArquivosIguais = this.validaPorTamanho(afInfoComparador, afInfoComparado);

if (abolArquivosIguais)
abolArquivosIguais = this.validaPorConteudo(afInfoComparador, afInfoComparado);

return abolArquivosIguais;

}

Agora que temos nossos métodos principais, vamos estrutura nosso projeto, como não precisamos de uma interface vamos fazer uma Console Application. Segue a estrutura básica:

Sem Título-2Pronto, temos o nosso projeto pronto 🙂

A primeira verificação de arquivos repetidos da minha máquina deu quase 2GB de imagens e 5 GB de mp3 🙂

Para baixar o código fonte, segue o link:

https://www.dropbox.com/s/vyztzsl7qr1tpzp/PhotoOrganizer.rar

Lembrando que o código foi compilado em .Net Framework 4.5 no Visual Studio 2013

 

Anúncios
Esse post foi publicado em .Net Framework 4.5, C#, LINQ, Orientação a Objeto, System.IO, VS2013 e marcado , , , , , , . Guardar link permanente.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s