C# - Copiando Arquivos textos e binários


Hoje vou mostrar como podemos copiar arquivos usando os recursos da classe System.IO e a linguagem C#.

Vamos criar um pequeno projeto Windows Forms que permitirá selecionar um arquivo binário ou texto e copiar o arquivo para outro local .

Para isso vamos usar os recursos das classes Stream, BinaryReader e BinaryWriter do namespace System.IO.

Abra o Visual C# 2010 Express Edition e no menu File clique em New Project;

Selecione o template Windows Forms Application e informe o nome CopiarArquivos;

No formulário padrão form1.cs vamos criar uma interface bem simples e intuitiva usando os seguintes controles:

Conforme o leiaute da figura abaixo:

Os namespaces usados no projeto são:

using System;
using System.Windows.Forms;
using System.IO;

No evento Click do botão - Copiar Arquivo - inclua o código a seguir:

private void btnCopiar_Click(object sender, EventArgs e)
        {
            if (rdbBinario.Checked)
            {
               if(validarArquivos())
                CopiarArquivoBinario(@txtOrigem.Text, @txtDestino.Text);
               else
                     MessageBox.Show("Não foi possível encontrar o arquivo Origem","Erro",MessageBoxButtons.OK,MessageBoxIcon.Information);
            }
            else if (rdbTexto.Checked)
            {
                if (validarArquivos())
                    CopiarArquivoTexto(txtOrigem.Text, txtDestino.Text);
                else
                    MessageBox.Show("Não foi possível encontrar o arquivo Origem", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Selecione o tipo de arquivo a ser copiado", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

O código acima verifica se o arquivo a ser copiado é binário ou texto e chama a rotina apropriada;

O código da rotina CopiarArquivoBinario() recebe dois argumentos : o arquivo de origem e o arquivo de destino. O seu código é descrito a seguir:

 static bool CopiarArquivoBinario(string nomeArquivoOrigem, string nomeArquivoDestino)
        {
            if (File.Exists(nomeArquivoOrigem) == false)
            {
                MessageBox.Show("Não foi possível encontrar o arquivo Origem","Erro",MessageBoxButtons.OK,MessageBoxIcon.Information);
                return false;
            }
            if (File.Exists(nomeArquivoDestino) == true)
            {
                if(MessageBox.Show("Já existe um arquivo com esse nome na pasta indicada, deseja sobrepor este arquivo?", "Sobrepor", MessageBoxButtons.YesNo)==DialogResult.No)
                   return false;
            }
            try
            {
                Stream s1 = File.Open(@nomeArquivoOrigem, FileMode.Open);
                Stream s2 =  File.Open(@nomeArquivoDestino, FileMode.Create);

                BinaryReader f1 = new BinaryReader(s1);
                BinaryWriter f2 = new BinaryWriter(s2);

                while (true)
                {
                    byte[] buf = new byte[10240];
                    int sz = f1.Read(buf, 0, 10240);
                    if (sz <= 0)
                        break;
                    f2.Write(buf, 0, sz);
                    if (sz < 10240)
                        break; // fim de arquivo
                }
                f1.Close();
                f2.Close();
                MessageBox.Show("Arquivo " + nomeArquivoOrigem +  " copiado com sucesso. ", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro ao copiar a o arquivo ...: " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }
        }

A parte do código destacada em azul é quem esta copiando o arquivo. Criamos dois streams: s1 e s2, um BinaryReader, f1 e um BinaryWriter f2;

A classe Stream define propriedades e métodos que permitem realizar operações genéricas com fluxo de bytes (streams) : ler , escrever, etc.

Nota: Um stream pode ser considerado um  fluxo sequêncial de bytes com um arquivo, um dispositivo de entrada/saida, um processo de comunicação entre dois pontos ou um socket TCP/IP. (Após esta explicação eu vou continuar a usar a palavra stream na sua forma original sem tradução.)

Usar Streams envolve as seguintes operações fundamentais

A classe BinaryReader lê tipos de dados primitivos como valores binários em uma codificação específica e a classe BinaryWriter grava tipos primitivos em binário em um fluxo e suporta cadeias de caracteres de escrita em uma codificação específica.(Um objeto BinaryWriter trabalha no nível mais baixo de Streams.)

A classe BinaryWriter é usada para escrever tipos primitivos como valores binários em um fluxo de codificação específica. Ela trabalha com objetos de fluxo que fornecem acesso aos bytes subjacentes. Para criar um objeto BinaryWriter, primeiro você tem que criar um objeto FileStream e depois passar o BinaryWriter ao método construtor.

Após criar os objetos é feita a leitura do arquivo origem em blocos de 1024 bytes escrevendo em seguida no destino. Esse processo é repetido até alcançar o final do arquivo.

Para copiar arquivos textos o procedimento é praticamente o mesmo, neste caso não precisamos usar as classes BinaryReader e BinaryWriter, ao invés disso usamos as classes StreamReader e StreamWriter conforme mostra o código abaixo:

 static bool CopiarArquivoTexto(string nomeArquivoOrigem, string nomeArquivoDestino)
        {
            if (File.Exists(nomeArquivoOrigem) == false)
            {
                MessageBox.Show("Não foi possível encontrar o arquivo Origem", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }

            if (File.Exists(nomeArquivoDestino) == true)
            {
                MessageBox.Show("Já existe um arquivo com esse nome na pasta indicada, deseja sobrepor este arquivo?", "Sobrepor", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                return false;
            }
         try
         {
           StreamReader f1 = new StreamReader(nomeArquivoOrigem);
           StreamWriter f2 = new StreamWriter(nomeArquivoDestino);

            while (true)
            {
                char[] buf = new char[1024];
                int sz = f1.Read(buf, 0, 1024);
                if (sz <= 0)
                    break;
                f2.Write(buf, 0, sz);
                if (sz < 1024)
                    break; // fim arquivo
            }
            f1.Close();
            f2.Close();
            return true;
         }
         catch (Exception ex)
         {
             MessageBox.Show("Erro ao copiar a o arquivo ...: " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Information);
             return false;
         }
        }

A classe StreamReader implementa um TextReader  que lê caracteres de um fluxo de bytes em uma codificação específica. Já a classe StreamWriter faz a mesma coisa para para escrever os caracteres em um stream.

O método Copy da classe File (File.Copy) também pode ser usada para copiar uma arquivo existente para um novo arquivo.

Pegue o projeto completo aqui: CopiarArquivosBinarios.zip

João 12:26 Se alguém me quiser servir, siga-me; e onde eu estiver, ali estará também o meu servo; se alguém me servir, o Pai o honrará.

João 12:27 Agora a minha alma está perturbada; e que direi eu? Pai, salva-me desta hora? Mas para isto vim a esta hora.

João 12:28 Pai, glorifica o teu nome. Veio, então, do céu esta voz: Já o tenho glorificado, e outra vez o glorificarei.

Referências:


José Carlos Macoratti