2016-05-15 101 views
0

我正在做一個簡單的程序,下載一堆文件。現在我想顯示用戶「xx剩餘時間」(就像你看到的uTorrent一樣)。FTP下載估計剩餘時間

到目前爲止,這是我得到

下載文件

// Download the file 
//Console.WriteLine("Downloading \"{0}\" from {1}...", node.Name, Config.FTP_HOST + "/" + node.DirectoryFileIsIn); 
FtpWebRequest request = CreateRequest("ftp://" + Config.FTP_HOST + "/" + node.DirectoryFileIsIn + "/" + node.Name, WebRequestMethods.Ftp.DownloadFile.ToString()); 
FtpWebResponse response = (FtpWebResponse)request.GetResponse(); 
Stream responseStream = response.GetResponseStream(); 
FileStream filestream = new FileStream(new_path, FileMode.Create); 

int chunkSize = 1024; 
long total = node.FileSize; 
int streamPosition = 0; 
while (true) 
{ 
    byte[] buffer = new byte[Math.Min(chunkSize, node.FileSize - streamPosition)]; 
    //byte[] buffer = new byte[chunkSize]; 
    int readBytes = responseStream.Read(buffer, 0, buffer.Length); 

    if (readBytes == 0) 
     break; 

    currentFileSizeDownloaded += readBytes; // total bytes downloaded 
    bytesSnapshot += readBytes; // for tracking download speed 
    streamPosition += readBytes; // for tracking response stream position 

    filestream.Write(buffer, 0, readBytes); 
} 

filestream.Flush(); 
//Console.WriteLine("Download Complete, status {0}", response.StatusDescription); 

response.Dispose(); 
filestream.Dispose(); 

response.Close(); 
filestream.Close(); 

捕獲字節下載(單獨的線程)

// Calculate total download time 
public static void CalculateDownloadTime() 
{ 
    bytesSnapshot = 0; 
    int waitTime = 10000; 
    Thread.Sleep(waitTime); // sleep 10 seconds 

    if (bytesSnapshot > 0) 
    { 
     double downloadSpeed = (bytesSnapshot/10); // bytes per second 
     long remainingTime = (totalFileSizeToDownload - currentFileSizeDownloaded)/(long)downloadSpeed; 
     Console.WriteLine("Download speed {0}", Formatting.FormatBytes((long)downloadSpeed)); 
     Console.WriteLine("Remaining time {0}", Formatting.FormatSeconds(remainingTime)); 
     Console.WriteLine(); 
    } 
    else 
    { 
     Console.WriteLine("byteSnapshot = 0"); // DEBUG 
     downloadTracker.Abort(); 
     return; 
    } 

    CalculateDownloadTime(); 
} 

輸出

Download speed 106,73 KB 
Remaining time 0:01:52 

Download speed 9,02 KB 
Remaining time 0:22:05 

Download speed 8,94 KB 
Remaining time 0:22:06 

Download speed 7,68 KB 
Remaining time 0:25:35 

Download speed 7,68 KB 
Remaining time 0:25:25 

Download speed 8,12 KB 
Remaining time 0:23:52 

Download speed 8,39 KB 
Remaining time 0:22:56 

Download speed 169,65 KB 
Remaining time 0:00:58 

Download speed 591,03 KB 
Remaining time 0:00:06 

Download speed 393,86 KB 
Remaining time 0:00:00 

byteSnapshot = 0 

正如你可以看到我做錯了..下載速度does not看起來現實給我的時間是路要走,但我無法弄清楚是怎麼回事錯..

我認爲我的問題在於計算下載速度,所以如果下載速度是正確的,時間將是固定的...

回答

0

我一直在測試,我想我找到了解決方案。

我創建2 BackgroundWorkers

  1. 下載過程
  2. 計算下載速度

下載過程這裏
沒有什麼太大的改變。我加了Stopwatch跟蹤的它需要下載x個字節的時間。 x字節數存儲在currentFileSizeDownloaded中,秒數存儲在secondsElapsed中。

// Download the file 
//Console.WriteLine("Downloading \"{0}\" from {1}...", node.Name, Config.FTP_HOST + "/" + node.DirectoryFileIsIn); 
FtpWebRequest request = CreateRequest("ftp://" + Config.FTP_HOST + "/" + node.DirectoryFileIsIn + "/" + node.Name, WebRequestMethods.Ftp.DownloadFile.ToString()); 
FtpWebResponse response = (FtpWebResponse)request.GetResponse(); 
Stream responseStream = response.GetResponseStream(); 
FileStream filestream = new FileStream(new_path, FileMode.Create); 

// Start stopwatch for calculating download speed 
Stopwatch stopwatch = new Stopwatch(); 
stopwatch.Start(); 

// Read/write downloaded bytes 
int chunkSize = 1024; 
long total = node.FileSize; 
int streamPosition = 0; 
while (true) 
{ 
    byte[] buffer = new byte[Math.Min(chunkSize, node.FileSize - streamPosition)]; 
    //byte[] buffer = new byte[chunkSize]; 
    int readBytes = responseStream.Read(buffer, 0, buffer.Length); 

    if (readBytes == 0) 
     break; 

    currentFileSizeDownloaded += readBytes; // total bytes downloaded 
    streamPosition += readBytes; // for tracking response stream position 

    filestream.Write(buffer, 0, readBytes); 
} 

// Stop the stopwatch 
stopwatch.Stop(); 
secondsElapsed += stopwatch.Elapsed.TotalSeconds; 

filestream.Flush(); 
//Console.WriteLine("Download Complete, status {0}", response.StatusDescription); 

response.Dispose(); 
filestream.Dispose(); 

response.Close(); 
filestream.Close(); 
} 

計算下載速度
這是我計算的下載速度,又沒有什麼太大的改變..我是從下載過程緩存secondsElapsedcurrentFileSizeDownloaded並使用這些精確的值,我DownloadSpeed計算(而不是使用我的Thread.Sleep()中的「10秒」)。

while (true) 
{ 
    cached_secondsElapsed = secondsElapsed; 
    cached_currentFileSizeDownloaded = currentFileSizeDownloaded; 

    Thread.Sleep(10000); // Sleep 10 seconds 

    long bytesDownloaded = currentFileSizeDownloaded - cached_currentFileSizeDownloaded; 
    double secondsItTook = secondsElapsed - cached_secondsElapsed; 

    if (bytesDownloaded > 0) 
    { 
     double downloadSpeed = ((double)bytesDownloaded/secondsItTook); // bytes per second 
     long remainingTime = (totalFileSizeToDownload - currentFileSizeDownloaded)/(long)downloadSpeed; 
     Console.WriteLine("Download speed {0}", Formatting.FormatBytes((long)downloadSpeed)); 
     Console.WriteLine("Remaining time {0}", Formatting.FormatSeconds(remainingTime)); 
     Console.WriteLine(); 
    } 
    else 
    { 
     Console.WriteLine("bytesDownloaded = 0"); // DEBUG 
     Application.Exit(); // Stop the app 
    } 
} 

輸出

Download speed 976,58 KB 
Remaining time 0:00:12 

Download speed 438,6 KB 
Remaining time 0:00:27 

Download speed 483,37 KB 
Remaining time 0:00:24 

Download speed 325,42 KB 
Remaining time 0:00:36 

Download speed 331,42 KB 
Remaining time 0:00:35 

Download speed 363,87 KB 
Remaining time 0:00:31 

Download speed 441,13 KB 
Remaining time 0:00:26 

Download speed 798,81 KB 
Remaining time 0:00:10 

Download speed 1,04 MB 
Remaining time 0:00:00 

bytesDownloaded = 0 

這是不準確的,但它是waaay比我以前有更好的,如果還有人有得到這個輸出更準確,給我的提示,請張貼他們作爲答覆/評論。