Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 扩展自定义可恢复下载类_C# - Fatal编程技术网

C# 扩展自定义可恢复下载类

C# 扩展自定义可恢复下载类,c#,C#,我的下载类中有一个名为DownloadProgressChanged的事件处理程序。它通过DownloadProgressChangedEventArgs类接受四个参数,它们是BytesReceived、TotalBytesToReceive、ProgressPercentage和CurrentSpeed 我可以下载和恢复文件。也阻止他们。现在添加下载ProgressEventArgs所需的数据让我感到困惑。主要问题是我不知道BytesReceived参数所需的信息在哪里。有人能给我指出正确的方

我的下载类中有一个名为DownloadProgressChanged的事件处理程序。它通过DownloadProgressChangedEventArgs类接受四个参数,它们是BytesReceived、TotalBytesToReceive、ProgressPercentage和CurrentSpeed

我可以下载和恢复文件。也阻止他们。现在添加下载ProgressEventArgs所需的数据让我感到困惑。主要问题是我不知道BytesReceived参数所需的信息在哪里。有人能给我指出正确的方向吗

public class Download
{
    public event EventHandler<DownloadProgressChangedEventArgs> DownloadProgressChanged;
    public event EventHandler DownloadCompleted;

    public bool stop = true; // by default stop is true
    // add option to get current downloaded size
    // add option get current download speed

    public void DownloadFile(string DownloadLink, string Path)
    {
        stop = false; // always set this bool to false, everytime this method is called

        long ExistingLength = 0;
        FileStream saveFileStream;

        if (File.Exists(Path))
        {
            FileInfo fileInfo = new FileInfo(Path);
            ExistingLength = fileInfo.Length;
        }

        if (ExistingLength > 0)
            saveFileStream = new FileStream(Path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
        else
            saveFileStream = new FileStream(Path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);


        var request = (HttpWebRequest)HttpWebRequest.Create(DownloadLink);
        request.AddRange((int)ExistingLength);
        try
        {
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                long FileSize = ExistingLength + response.ContentLength; //response.ContentLength gives me the size that is remaining to be downloaded
                using (var stream = response.GetResponseStream())
                {
                    byte[] downBuffer = new byte[1024 * 1000];
                    int byteSize;
                    var sw = new Stopwatch();
                    while ((byteSize = stream.Read(downBuffer, 0, downBuffer.Length)) > 0)
                    {
                        saveFileStream.Write(downBuffer, 0, byteSize);

                        var args = new DownloadProgressChangedEventArgs();
                        //args.BytesReceived = ;
                        args.TotalBytesToReceive = FileSize;
                        args.ProgressPercentage = (byteSize / (int)FileSize) * 100;
                        //args.CurrentSpeed = ;
                        OnDownloadProgressChanged(args);

                        if (stop == true) break;
                    }
                }
            }
        }
        catch (WebException e)
        {
            string filename = System.IO.Path.GetFileName(Path);
            System.Windows.MessageBox.Show(e.Message, filename);
            saveFileStream.Dispose(); //dispose filestream
            return; //not needed because this is the last line of the method, but let's keep it here
        }
    }

    public void StopDownload()
    {
        stop = true;
    }

    protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e)
    {
        EventHandler<DownloadProgressChangedEventArgs> handler = DownloadProgressChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    protected virtual void OnDownloadCompleted(EventArgs e)
    {
        EventHandler handler = DownloadCompleted;
        if (handler != null)
        {
            handler(this, e);
        }
    }
}

public class DownloadProgressChangedEventArgs : EventArgs
{
    public long BytesReceived { get; set; }
    public long TotalBytesToReceive { get; set; }
    public int ProgressPercentage { get; set; }
    public double CurrentSpeed { get; set; }
}
公共类下载
{
公共事件事件处理程序下载进度已更改;
公共事件事件处理程序下载完成;
public bool stop=true;//默认情况下,stop为true
//添加选项以获取当前下载的大小
//添加选项获取当前下载速度
公共void下载文件(字符串下载链接,字符串路径)
{
stop=false;//每次调用此方法时,始终将此bool设置为false
长现存长度=0;
文件流保存文件流;
if(File.Exists(Path))
{
FileInfo FileInfo=新的FileInfo(路径);
ExistingLength=fileInfo.Length;
}
如果(现有长度>0)
saveFileStream=newfilestream(路径,FileMode.Append,FileAccess.Write,FileShare.ReadWrite);
其他的
saveFileStream=newfilestream(路径,FileMode.Create,FileAccess.Write,FileShare.ReadWrite);
var request=(HttpWebRequest)HttpWebRequest.Create(DownloadLink);
request.AddRange((int)ExistingLength);
尝试
{
使用(var response=(HttpWebResponse)request.GetResponse())
{
long FileSize=ExistingLength+response.ContentLength;//response.ContentLength为我提供了剩余下载的大小
使用(var stream=response.GetResponseStream())
{
字节[]下行缓冲区=新字节[1024*1000];
int字节大小;
var sw=新秒表();
而((byteSize=stream.Read(downBuffer,0,downBuffer.Length))>0)
{
saveFileStream.Write(下行缓冲区,0,字节大小);
var args=new DownloadProgressChangedEventArgs();
//args.BytesReceived=;
args.TotalBytesToReceive=文件大小;
args.ProgressPercentage=(字节大小/(整数)文件大小)*100;
//args.CurrentSpeed=;
OnDownloadProgressChanged(args);
如果(停止==真)中断;
}
}
}
}
捕获(WebE例外)
{
字符串文件名=System.IO.Path.GetFileName(路径);
System.Windows.MessageBox.Show(e.Message,文件名);
saveFileStream.Dispose();//Dispose filestream
return;//不需要,因为这是该方法的最后一行,但让我们将其保留在这里
}
}
公共void StopDownload()
{
停止=真;
}
受保护的虚拟无效OnDownloadProgressChanged(DownloadProgressChangedEventArgs e)
{
EventHandler=DownloadProgressChanged;
if(处理程序!=null)
{
处理者(本,e);
}
}
已完成受保护的虚拟无效OnDownloadCompleted(事件参数e)
{
EventHandler=DownloadCompleted;
if(处理程序!=null)
{
处理者(本,e);
}
}
}
公共类下载ProgressChangedEventArgs:EventArgs
{
公共长字节接收{get;set;}
公共长TotalByTestOreReceive{get;set;}
公共整数百分比{get;set;}
公共双电流速度{get;set;}
}

而且byteSize一点也不改变。出于某些原因,它始终保持不变。

这是一个很棒的无bug工作可恢复下载类,有很多改进:

public class Download
{
    public event EventHandler<DownloadStatusChangedEventArgs> DownloadStatusChanged;
    public event EventHandler<DownloadProgressChangedEventArgs> DownloadProgressChanged;
    public event EventHandler DownloadCompleted;

    public bool stop = true; // by default stop is true

    public void DownloadFile(string DownloadLink, string Path)
    {
        stop = false; // always set this bool to false, everytime this method is called

        long ExistingLength = 0;
        FileStream saveFileStream;

        if (File.Exists(Path))
        {
            FileInfo fileInfo = new FileInfo(Path);
            ExistingLength = fileInfo.Length;
        }

        if (ExistingLength > 0)
            saveFileStream = new FileStream(Path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
        else
            saveFileStream = new FileStream(Path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);

        var request = (HttpWebRequest)HttpWebRequest.Create(DownloadLink);
        request.Proxy = null;
        request.AddRange(ExistingLength);

        try
        {
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                long FileSize = ExistingLength + response.ContentLength; //response.ContentLength gives me the size that is remaining to be downloaded
                bool downloadResumable; // need it for sending empty progress

                if ((int)response.StatusCode == 206)
                {
                    Console.WriteLine("Resumable");
                    var downloadStatusArgs = new DownloadStatusChangedEventArgs();
                    downloadResumable = true;
                    downloadStatusArgs.ResumeSupported = downloadResumable;
                    OnDownloadStatusChanged(downloadStatusArgs);
                }
                else // sometimes a server that supports partial content will lose its ability to send partial content(weird behavior) and thus the download will lose its resumability
                {
                    Console.WriteLine("Resume Not Supported");
                    ExistingLength = 0;
                    var downloadStatusArgs = new DownloadStatusChangedEventArgs();
                    downloadResumable = false;
                    downloadStatusArgs.ResumeSupported = downloadResumable;
                    OnDownloadStatusChanged(downloadStatusArgs);
                    // restart downloading the file from the beginning because it isn't resumable
                    // if this isn't done, the method downloads the file from the beginning and starts writing it after the previously half downloaded file, thus increasing the filesize and corrupting the downloaded file
                    saveFileStream.Dispose(); // dispose object to free it for the next operation
                    File.WriteAllText(Path, string.Empty); // clear the contents of the half downloaded file that can't be resumed
                    saveFileStream = saveFileStream = new FileStream(Path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); // reopen it for writing
                }

                using (var stream = response.GetResponseStream())
                {
                    byte[] downBuffer = new byte[4096];
                    int byteSize = 0;
                    long totalReceived = byteSize + ExistingLength;
                    var sw = new Stopwatch();
                    sw.Start();
                    while ((byteSize = stream.Read(downBuffer, 0, downBuffer.Length)) > 0)
                    {
                        saveFileStream.Write(downBuffer, 0, byteSize);
                        totalReceived += byteSize;

                        var args = new DownloadProgressChangedEventArgs();
                        args.BytesReceived = totalReceived;
                        args.TotalBytesToReceive = FileSize;
                        float currentSpeed = totalReceived / (float)sw.Elapsed.TotalSeconds;
                        args.CurrentSpeed = currentSpeed;
                        if (downloadResumable == true)
                        {
                            args.ProgressPercentage = ((float)totalReceived / (float)FileSize) * 100;
                            long bytesRemainingtoBeReceived = FileSize - totalReceived;
                            args.TimeLeft = (long)(bytesRemainingtoBeReceived / currentSpeed);
                        }
                        else
                        {
                            //args.ProgressPercentage = Unknown;
                            //args.TimeLeft = Unknown;
                        }
                        OnDownloadProgressChanged(args);

                        if (stop == true) 
                            return;
                    }
                    sw.Stop();
                }
            }
            var completedArgs = new EventArgs();
            OnDownloadCompleted(completedArgs);
            saveFileStream.Dispose();
        }
        catch (WebException e)
        {
            string filename = System.IO.Path.GetFileName(Path);
            Console.WriteLine(e.Message);
            saveFileStream.Dispose();
            return; //not needed because this is the last line of the method, but let's keep it here
        }
    }

    public void StopDownload()
    {
        stop = true;
    }

    protected virtual void OnDownloadStatusChanged(DownloadStatusChangedEventArgs e)
    {
        EventHandler<DownloadStatusChangedEventArgs> handler = DownloadStatusChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e)
    {
        EventHandler<DownloadProgressChangedEventArgs> handler = DownloadProgressChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    protected virtual void OnDownloadCompleted(EventArgs e)
    {
        EventHandler handler = DownloadCompleted;
        if (handler != null)
        {
            handler(this, e);
        }
    }
}

public class DownloadStatusChangedEventArgs : EventArgs
{
    public bool ResumeSupported { get; set; }
}

public class DownloadProgressChangedEventArgs : EventArgs
{
    public long BytesReceived { get; set; }
    public long TotalBytesToReceive { get; set; }
    public float ProgressPercentage { get; set; }
    public float CurrentSpeed { get; set; } // in bytes
    public long TimeLeft { get; set; } // in seconds
}
公共类下载
{
公共事件事件处理程序下载状态已更改;
公共事件事件处理程序下载进度已更改;
公共事件事件处理程序下载完成;
public bool stop=true;//默认情况下,stop为true
公共void下载文件(字符串下载链接,字符串路径)
{
stop=false;//每次调用此方法时,始终将此bool设置为false
长现存长度=0;
文件流保存文件流;
if(File.Exists(Path))
{
FileInfo FileInfo=新的FileInfo(路径);
ExistingLength=fileInfo.Length;
}
如果(现有长度>0)
saveFileStream=newfilestream(路径,FileMode.Append,FileAccess.Write,FileShare.ReadWrite);
其他的
saveFileStream=newfilestream(路径,FileMode.Create,FileAccess.Write,FileShare.ReadWrite);
var request=(HttpWebRequest)HttpWebRequest.Create(DownloadLink);
Proxy=null;
request.AddRange(现有长度);
尝试
{
使用(var response=(HttpWebResponse)request.GetResponse())
{
long FileSize=ExistingLength+response.ContentLength;//response.ContentLength为我提供了剩余下载的大小
bool downloadreamable;//发送空进度时需要它
如果((int)response.StatusCode==206)
{
控制台写入线(“可恢复”);
var downloadStatusArgs=new DownloadStatusChangedEventArgs();
DownloadResubable=true;
downloadStatusArgs.ResumeSupported=DownloadResupable;
OnDownloadStatusChanged(downloadStatusArgs);
}
else//有时,支持部分内容的服务器将失去发送部分内容的能力(奇怪的行为),从而导致下载失败