Eric
Eric

Reputation: 57

Progress Bar for file transfer

Hi there good day to all. I'm creating a file transfer for LAN right now and I want to put a progress bar in that file transfer so the user can see the progress of the transmission. How can I manipulate the progress bar based on the size and transfer rate of the file?

Example: I am sending a 10mb file to another computer in the network. I want the progress to show the remaining time or how long it will take to complete the transmission.

Can anyone here give me an idea on what to do?

Upvotes: 0

Views: 5456

Answers (4)

MRM
MRM

Reputation: 435

The best way is put your transfer file in one Thread and update your status of progress by invoke method. in my my code I use FTP for transferring one zip file. here is my solution and sample code:

1-in your main form you must have progress bar, in my code I name it "prbSendata"

2- call the transfer Thread:

Thread oThread = new Thread(Transfer);
oThread.Start(this);
this.Cursor = Cursors.WaitCursor;

3- you must have Transfer File like this:

private static void Transfer(object obj)
{
    frmMain frmPar = (frmMain)obj;
    try
    {    
        string filename=_strStartingPath + @"\" + _strZipFileName + ".zip";
        FileInfo fileInf = new FileInfo(filename);
        string uri = _strFtpAddress + "/" + fileInf.Name;
        FtpWebRequest reqFTP;

        // Create FtpWebRequest object from the Uri provided

        reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));

        // Provide the WebPermission Credintials

        reqFTP.Credentials = new NetworkCredential(_strFtpUserName, _strFtpPassword);

        // By default KeepAlive is true, where the control connection is 
        // not closed after a command is executed.

        reqFTP.KeepAlive = false;

        // Specify the command to be executed.

        reqFTP.Method = WebRequestMethods.Ftp.UploadFile;

        // Specify the data transfer type.

        reqFTP.UseBinary = true;

        // Notify the server about the size of the uploaded file

        reqFTP.ContentLength = fileInf.Length;

        // The buffer size is set to 2kb

        int buffLength = 2048;
        byte[] buff = new byte[buffLength];
        int contentLen;

        // Opens a file stream (System.IO.FileStream) to read the file to be uploaded

        FileStream fs = fileInf.OpenRead();

        // Stream to which the file to be upload is written

        Stream strm = reqFTP.GetRequestStream();

        // Read from the file stream 2kb at a time

        contentLen = fs.Read(buff, 0, buffLength);
        frmPar.prbSendata.Control.Invoke((MethodInvoker)(() =>{
            frmPar.prbSendata.Minimum=0;
            frmPar.prbSendata.Maximum=100;
        }));

        // Till Stream content ends
        long loadSize=0;
        while (contentLen != 0)
        {
            // Write Content from the file stream to the FTP Upload Stream
            loadSize+=contentLen;
            frmPar.prbSendata.Control.Invoke((MethodInvoker)(() =>{
                frmPar.prbSendata.Value=(int)(loadSize*100/fileInf.Length);
                }));

            strm.Write(buff, 0, contentLen);
            contentLen = fs.Read(buff, 0, buffLength);

        }

        // Close the file stream and the Request Stream

        strm.Close();
        fs.Close();
    }
    catch (Exception err)
    {
        MessageBox.Show("Error: " + err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

    frmPar.txtResult.Invoke((MethodInvoker)(() =>frmPar.Cursor = Cursors.Default));

}

Upvotes: 0

Elastep
Elastep

Reputation: 3408

1) You should send files by parts in loop. So you can determine what is the progress in percents.

2) You should do it in BackgroundWorker (it's a component available from toolbox). Background worker has a ProgressChanged event that can be fired by calling ReportProgress in the DoWork method. Also don't forget to set the property WorkerReportsProgress to true.

3) In ProgressChanged event change the UI you need to correspond the current status.

Upvotes: 0

apocalypse
apocalypse

Reputation: 5884

1) Make a class named hmmm FileSender

2) Your class will send data grouped into Blocks

3) Add option to your class, like MaxBlockSize - it will be maximum amount of data that you will send in one block

4) make a delegate OnBlockTransfer or something like that

5) Make method like FileSender.Send() ...

This method will start file sending, after each block, your class will execute your delegate. In your method called by delegate you can refresh your status bar.

Transfer speed is easy; you need to check system time, and count data that you sent.

Upvotes: 0

IvanL
IvanL

Reputation: 2485

Take a look at http://www.codeproject.com/KB/files/Copy_files_with_Progress.aspx it might get you what you want or at least set in the right direction.

Upvotes: 2

Related Questions