[C#] Copia con barra de progreso

Pubicado en7 comentariosCategoríasProgramación

A veces nuestros programas necesitan copiar ficheros de gran tamaño y el System.File.Copy nos «bloquea» la interfaz.
Además, siempre es interesante de cara al usuario poder mostrar el progreso de la copia impidiendo que se nos aburra y acabemos atendiendo llamadas del estilo «es que esto se queda colgado copiando»

Hace algún tiempo me hice una función para poder copiar ficheros y mostrar un progreso.
A mayores informa de cuántos Mb se han copiado del total (algo del estilo «50 Mb de 510Mb») y muestra la tasa de transferencia expresada en Mb/s.

Os la dejo aquí:

/// incluimos el namespace de manejo de ficheros y el de objetos de interfaz de escritorio de Windows:
using System.IO;
using System.Windows.Forms;

/// <summary>
/// Realiza una copia de un fichero y muestra el progreso en una barra
/// </summary>
/// <param name="rutaOrigen">Ruta completa del fichero que queremos copiar</param>
/// <param name="rutaDestino">Ruta completa de destino</param>
/// <param name="BufferSize">Tamaño del buffer de copia</param>
/// <param name="prg">Barra de progreso en donde se reportará el resultado</param>
/// <param name="lbl">Label de información en donde se reportará el progreso</param>
/// <returns>Resultado de la operación</returns>
public bool CopiarProgreso(string rutaOrigen, string rutaDestino, int BufferSize, ProgressBar prg, Label lbl)
{
    try
    {
        int segundos;
        double oldMB = 0.0F;
        double media = 0.0F;

        //Preparamos los filestreams. Uno para lectura y otro para escritura.
        FileStream ReadFile = new FileStream(rutaOrigen, FileMode.Open, FileAccess.Read);
        FileStream WriteFile = new FileStream(rutaDestino, FileMode.CreateNew, FileAccess.Write);

        int inicioLectura = 0;
        int tamañoBuffer = BufferSize;
        prg.Maximum = (Int32)ReadFile.Length;
        prg.Value = 0;
        byte[] buffer = new byte[tamañoBuffer];
        int result = 1;
        segundos = DateTime.Now.Second;

        while (result != 0)
        {
            result = ReadFile.Read(buffer, 0, tamañoBuffer);
            inicioLectura += tamañoBuffer;
            prg.Value += result;
            lbl.Text = "Copiados " + ConvertToMB(prg.Value).ToString() + " MB de " +
                                  ConvertToMB(prg.Maximum).ToString() + " MB";
            lbl.Text += " (" + ConvertToMB(media).ToString() + " MB/seg)";

            WriteFile.Write(buffer, 0, result);
            if (Math.Abs(DateTime.Now.Second - segundos) < 1) //actualizamos los valores cada segundo
            {
                media = (media + (prg.Value - oldMB)) / 2;
                segundos = DateTime.Now.Second;
                oldMB = prg.Value;
            }
            Application.DoEvents();
        }
        ReadFile.Close();
        WriteFile.Close();
        ReadFile.Dispose();
        WriteFile.Dispose();

        lbl.Text = "Copia finalizada.";
        Application.DoEvents();

        return true;
    }
    catch (Exception ex)
    {
        return false;
    }
}

/// <summary>
/// Convierte bytes en Mbytes
/// </summary>
/// <param name="sizeBytes">Bytes a convertir a Mb</param>
/// <returns>Mbytes</returns>
private double ConvertToMB(double sizeBytes)
{
    return Math.Round(Convert.ToDouble((sizeBytes / 1024) / 1024), 2);
}

7 comentarios en “[C#] Copia con barra de progreso”

  1. Hola, muchísimas gracias por exponer tu trabajo, me ha servido de mucho. Hice un programa para hacer replicas de mis respaldos pero como bien mencionas, era aburrido esperar el resultado final sin saber cómo iba el progreso. Muy buen aporte

    1. Hola Jesús.

      Me alegra que te resultase útil mi artículo. Precisamente lo puse por eso, por si a alguien más le resultaba tedioso esperar y esperar sin saber como iba la cosa.

      Gracias a ti por tu visita y tu comentario.

  2. Hola , me parece excelente que compartieras ese código , la verdad encontré su pagina y esta muy interesante .

    ¿De casualidad tienes el programa de este código para verlo funcionar y correrlo con F11 en el IDE?

  3. Hola Fabián.

    Muchas gracias por tu comentario. El código completo de la aplicación no lo tengo ya que esto era una utilidad dentro de un programa mucho mayor. No obstante es bastante sencillo de implementar en una aplicación de prueba.

    Un saludo.

Responder a Paola Ruiz Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *