Click here to Skip to main content
11,704,315 members (54,933 online)
Click here to Skip to main content

Tagged as

Filecopy Control with Progress Information

, 6 May 2014 CPOL 12.8K 1.2K 15
Rate this:
Please Sign up or sign in to vote.
This is a Windows Forms control to copy a file with progress information

Introduction

Every time I download a file via internet browser, I see the progress information presented by the download statusbar. I wanted to have a control with the same behavior for my application development. Searching the web, I found some good sources for realizing the copy process but no control with progress information. Therefore, I started to develop my own.

Background

I found a basic idea in the article of a web coding portal as follows:

' social.msdn.microsoft.com/Forums/en-US/04bf3781-23ae-4629-9bc3-10f0cdfc8629/how-to-use-progress-bar-to-vbnet-form-for-copy-a-file?forum=Vsexpressvb
' by Paul IshakMVP

Based on this idea, I developed the control. The control is a usercontrol that hosts a progressbar and a label control.

Using the Code

In the attached ZIP file, you may find a Visual Studio 2013 project with two projects inside - the project for the usercontrol and a test project. Please compile the project and then attach the DLL file (FileCopyProgress.dll) from the bin\debug folder to the Visual Studio toolbox. If done, you may use the control as usual by dropping it onto a Windows Form.

The control has some extended customer properties. Before using the control, you may set the values of these properties by code in the parent form.

Extended Properties

Copy FromInsert complete path with full filename you like to copy.
Copy ToInsert complete target path with filename of the duplication.
Localized Strings These strings are displayed by the control.
Message Format

Build a format string that commands which message should be shown. Insert one or more command letters (uppercase) where the letter sequence is whatever. Use:
T to show file length
C to show current bytes copied
S to show transfer speed
R to show remaining time
example: TSR

Progressbar colorChoose a color for the progress bar
Progressbar StyleChoose a style of the progress bar
Show Info labelIf true show it, if false hide it.
Start copying

Set this value to true to activate copy process.
example:
FileCopyProgress.START = true

I would like to concentrate on the important parts and leave away the self explaining parts to keep this article short.

In the section where the variables are declared, you will find some constants. We need them to compute the different units of the file length. Notice that we have a hierarchy from bytes to Terabytes done by a multiplication of 1024 bytes (= 1 KB).

' ## Constants
 Const KB As Long = 1024
 Const MB As Long = KB * 1000
 Const GB As Long = MB * 1000
 Const TB As Long = GB * 1000
 Const M As Long = 60
 Const H As Long = M * 60
 Const D As Long = H * 24
 <Description("Localized strings"), DisplayName("Localized strings"), _
 Browsable(True), Category("extendedProperties")> _
 Public Property msgStrings As Array

In the section of the extended properties, we will have a look at the top of each property. The property bodies are self explaining. With "DisplayName", you can set the Property Name as it will be shown in the property grid. This name can be different from the property name in the source code. For example, to put spaces in the shown name for better reading. With "Category", you will define a new category for a better sorting of the properties in the property grid with the built in sorting function.

Now we would like to examine the main function "CopyFile" which is called by the property "START" if its property value is set to TRUE (FileCopyProgress1.START = TRUE) inside an event of the parent form. For example, the click event of a button.

At the beginning, we will check if the origin file to be copied is saved at the named path (Property COPYFROM). We do this using System.IO function exists. Next, we check if the file exists in the target folder. If it exists, we delete it with the System.IO function file.delete.

Private Sub CopyFile()

       ' (C) This code is based on an idea of a developer published:
       ' http://www.vb-paradise.de/index.php/Thread/29443-Datein-kopieren-mit-Fortschritt-und-verbleibender-Zeit/

       Try
           Cursor.Current = Cursors.WaitCursor

           ' check file, if exists delete it
           If File.Exists(COPYTO) Then
               File.Delete(COPYTO)
           End If
           ' check original file if exists copy it
           If File.Exists(COPYFROM) Then

To monitor the copy process, we would like to copy the file byte by byte. Doing it this way gives us the possibilities to compute the values of rest bytes to copy, transfer speed and remaining time.
To copy byte by byte, we need two file streams one to read the byte from the original file and the other one to write the byte to create the duplicate. We call this copying byte by byte streaming. To do this, we need a special function of .NET the filestreaming object. Before we can use it, we have to initialize the filestreaming objects.

' Open filestreams for reading original file and writing the copy
fromStream = New FileStream(COPYFROM, FileMode.Open)
toStream = New FileStream(COPYTO, FileMode.CreateNew)

The parameters of the filestreaming objects are filepath (COPYTO and COPYFROM) and streaming mode (Open and CreateNew). Remember COPYTO and COPYFROM are extended properties as described above.

One of the information that can be shown in the info label of our control is the (origin) file length. We get this value with the command fromstream.length as a returned value in bytes. To shorten the text of the info label, we have to convert the file length in kilobytes/megabytes a.s.o. To do this, we use the declared constants.

' get file length in byte
total = fromStream.Length

' convert file length to KB-MB-GB-TB
If total <= KB Then
    msg1 = total.ToString & " Byte"
ElseIf total > KB And total <= MB Then
    intTemp = Math.Round(total / KB, 0)
    msg1 = intTemp.ToString & " KB"
ElseIf total > MB And total <= GB Then
    intTemp = Math.Round(total / MB, 0)
    msg1 = intTemp.ToString & " MB"
ElseIf total > GB And total <= TB Then
    intTemp = Math.Round(total / GB, 0)
    msg1 = intTemp.ToString & " GB"
ElseIf total >= TB Then
    intTemp = Math.Round(total / TB, 0)
    msg1 = intTemp.ToString & " TB"
End If

Now we have to capture the current time from the computers system clock to use it as the base for computing the elapsed time. We will need this information to compute the remaining time we need. After this, we can start a loop for the byte by byte copying (read/write process).

' Get Time
startTime = DateTime.Now

Do ' copy byte by byte
    '  check if canceled
    If cancel Then
        fromStream.Close()
        toStream.Close()
        Exit Sub
    End If

    ' read original byte
    Dim read As Integer = fromStream.Read(buffer, 0, buffer.Length)
    ' create the copy and write the byte into the copy
    toStream.Write(buffer, 0, read)
    ' monitor read status
    current += read
    ' compute done percentage for progressbar
    Dim Prozent As Integer = current * 100 / total
    ProgressBar1.Value = Prozent
    ' compute time used
    eta = startTime.Subtract(DateTime.Now)
    ' compute remaining kilobytes to copy and remaining time
    kbRemaining = (current - total) / 1024
    If eta.Seconds <> 0 Then
        'KB/sec
        kbs = Math.Round((current / 1024) / (eta.Seconds), 2)
        secRemaining = kbRemaining / kbs
    End If

After copying with fromStream.Read / toStream.write, we compute the percentage of the copied bytes to set the value of the progress bar. Next, we compute the time used for copying. This will give us the value for the transfer speed and leads us direct to compute the value for the remaining time. We use math.round function because we don't want to display the values with decimal figures.

At least we go to convert the values of the copied file length, the speed and the remaining time in the same way as we had done with the origin file length just before (see above).

Now we are ready to build the string of the info label control. We are able to choose what value may be displayed and what value may be hidden. This is done by setting the value of the property ShowLabel. This value contains uppercase command letters TCSR. Each letter represents one value:
T = origin file length to copy C = current file length copied, S = transfer speed and R = remaining time. Example: To show the file length to copy the speed and the remaining time, you have to set the property value to: TSR.

' build message string
Dim strTemp As String = ""
If InStr(msgFormat, "T") Then strTemp = msg1
If InStr(msgFormat, "C") Then
    If strTemp <> "" Then strTemp = strTemp & " | "
    strTemp = strTemp & msg2
End If
If InStr(msgFormat, "S") Then
    If strTemp <> "" Then strTemp = strTemp & " | "
    strTemp = strTemp & msg3
End If
If InStr(msgFormat, "R") Then
    If strTemp <> "" Then strTemp = strTemp & " | "
    strTemp = strTemp & msg4
End If

' show info
lblmsg.Text = strTemp

To initialize the values of the localized strings and the controls, we do this in the New() Event of our user control. The localized strings can be changed by using the property msgStrings. The strings are used to build the message of the info label control and as the title of the error message of the try/catch function.

Public Sub New()

    ' Dieser Aufruf ist für den Designer erforderlich.
    InitializeComponent()

    ' Transfer usercontrol property values to label control
    With lblmsg
        .Font = Me.Font
        .ForeColor = Me.ForeColor
        .BackColor = Me.BackColor
        .Image = Me.BackgroundImage
    End With

    ' ini message string array
    _msgStrings(0) = " Sec."
    _msgStrings(1) = " Min."
    _msgStrings(2) = " Hrs."
    _msgStrings(3) = " Days"
    _msgStrings(4) = "Error!"
End Sub

We use the font/forecolor/backcolor/image property of our usercontrol to set the values of the hosted label control.

History

  • 2014/03/25 Correction of multiplication factors of the constants
  • 2014/05/07 Added picture

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

hgbecker
Founder TechDoc G. Becker
Germany Germany
I'am developing Applications since the Comodore 64 Computer was available to the marked.
At present I'm programming in Visual Studio 2012 using C# and mostly Visual Basic.
Sorry for Language mistakes but as a German English is not my native Language. But I hope anyone is able to understand me.

Best Regards from Germany
Happy coding
Guenter

You may also be interested in...

Comments and Discussions

 
SuggestionOverflow Exception Pin
Member 1066424625-Apr-15 12:32
memberMember 1066424625-Apr-15 12:32 
SuggestionA picture would be nice Pin
GeekforChrist13-Apr-14 7:42
memberGeekforChrist13-Apr-14 7:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150819.1 | Last Updated 6 May 2014
Article Copyright 2014 by hgbecker
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid