Link to home
Create AccountLog in
Avatar of CompuFit
CompuFit

asked on

Copying file: what is the actual file size during copy

Hey,

I copy a file from one folder to another folder (locally and/or through network) with a backgroundworker.
Before I start the copy, I start a timer. The timer will check for the file size of the new copied file each x seconds. Then showing the file sizes.
Example:
10MB/100MB
20MB/100MB
30MB/100MB
....
100MB/100MB
After the copying I stop the timer again.
But the size is always the same (ex 100MB/100MB, 100%).

See my code below
I there any other way for showing the actual size of the file?
private int Report_SetTimer = 9;
 
private void bwWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int p = e.ProgressPercentage;
if (p == Report_SetTimer)
{
  tmrFileTransfer.Enabled = (bool)e.UserState;
}      
}
 
private double sizeInMB(long sizeInBytes)
        {
            return sizeInMB(sizeInBytes, 2);
        }
 
        private double sizeInMB(long sizeInBytes, int decimals)
        {
            double sizeInMb = 0;
            if (sizeInBytes > 0)
            {
                sizeInMb = sizeInBytes / (1024 * 1024);
            }
            sizeInMb = Math.Round(sizeInMb, decimals);
            return sizeInMb;
        }
 
//make a local copy
.......code...........
System.IO.FileInfo fileInfo = new System.IO.FileInfo(isoFilePath);
_FileTransferTotalSize = fileInfo.Length;
_FileTransferCurrentFile = isoFilePathLocal;
//start timer
bwWorker.ReportProgress(Report_SetTimer, true);
System.IO.File.Copy(isoFilePath, isoFilePathLocal, true);
//stop timer
bwWorker.ReportProgress(Report_SetTimer, false);   
.......code...........
              
 
long _FileTransferTotalSize = 0;
long _FileTransferCurrentSize = 0;
string _FileTransferCurrentFile = null;
        private void tmrFileTransfer_Tick(object sender, EventArgs e)
        {
            if (_FileTransferCurrentFile != null)
            {
                if (System.IO.File.Exists(_FileTransferCurrentFile))
                {
                    System.IO.FileInfo fileInfo = new System.IO.FileInfo(_FileTransferCurrentFile);
                    _FileTransferCurrentSize = fileInfo.Length;
                }
                else
                {
                    _FileTransferCurrentSize = 0;
                }
                double percentage = 0;
                if (_FileTransferTotalSize > 0)
                {
                    percentage = (_FileTransferCurrentSize / _FileTransferTotalSize) * 100; //always 100%!!
                }
                double totalSizeInMb = sizeInMB(_FileTransferTotalSize);
                double currentSizeInMb = sizeInMB(_FileTransferCurrentSize);   //always the same
       
            }
            
        }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of REA_ANDREW
REA_ANDREW
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Avatar of CompuFit
CompuFit

ASKER

Do you have any sample code?
It's because:

long _FileTransferTotalSize = 0;
long _FileTransferCurrentSize = 0;

Are long data types and when you divide them you will always end up with a long. Multiplying them by 100 will always be 1*100 since long do not support decimal places. So 50/100 equals .50 but a long will result in this being 1. Change or convert your variables above to decimal or double and then do your calculation.
I have found my solution, the code
long _FileTransferTotalSize = 0;
        long _FileTransferCurrentSize = 0;
        string _FileTransferCurrentFile = null;       
        int _blockSize = 1024 * 1024; //1MB default per part
        private void copyFile(string pSource, string pDestination)
        {
            if (pSource != null)
            {
                if (System.IO.File.Exists(pSource))
                {
                    System.IO.FileInfo fileInfo = new System.IO.FileInfo(pSource);
                    _FileTransferTotalSize = fileInfo.Length;
                    _FileTransferCurrentSize = 0;
 
                    FileStream fsDestination = new FileStream(pDestination, FileMode.Create);
 
                    using (FileStream fsSource = new FileStream(pSource, FileMode.Open))
                    {
                        byte[] temp = new byte[this._blockSize];
                        int bytesRead;
                        do
                        {
                            bytesRead = fsSource.Read(temp, 0, this._blockSize);
 
                            byte[] copybuffer = new byte[bytesRead];
                            Array.Copy(temp, copybuffer, bytesRead);
 
                            fsDestination.Write(copybuffer, 0, bytesRead);
                            _FileTransferCurrentSize = fsDestination.Position;
 
                            double percentage = 0;
                            if (_FileTransferTotalSize > 0)
                            {
                                percentage = (((double)_FileTransferCurrentSize / (double)_FileTransferTotalSize)) * 100;
                                percentage = Math.Round(percentage);
                            }
                            double totalSizeInMb = sizeInMB(_FileTransferTotalSize);
                            double currentSizeInMb = sizeInMB(_FileTransferCurrentSize);
                            
                           //showing percentage....
 
 
                        } while (bytesRead > 0);
                    }
                    fsDestination.Close();
                }
            }
        }

Open in new window

I see that you are casting those variables to double now when doing your division. Without the cast this solution would not provide the desired results either.