HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Resumable HTTP download class

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
downloadclasshttpresumable

Problem

Any suggestions, corrections and advice would be very nice and much appreciated.

```
public class Download
{
public event EventHandler DownloadStatusChanged;
public event EventHandler 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

Solution

I would not directly write to the console.

You are best off building an ILogger interface, then create a ConsoleLogger class that is passed as an ILogger to the constructor.

public interface ILogger
{
    void LogMessage(string message, params Object[] args);
}

public class ConsoleLogger : ILogger
{
    public void LogMessage(string message, params Object[] args)
    {
        Console.WriteLine(string.Format(message, args));
    }
}


This allows you to break responsibilities away, and if in the future you wish to log messages directly to the Event Log instead, this allows you to make a class:

public class EventLogger : ILogger
{
    // ...
}


In the class handling all your work above (no class name is supplied) you would add:

private ILogger _Logger;

public ClassName(ILogger logger)
{
    _Logger = logger;
}


And modify all the Console.WriteLine calls to:

logger.LogMessage(/* ... */);


This is much more extensible, and allows you to unit test easier as well.

Additionally, if you wish to support a lack of a ILogger:

if (logger != null) { logger.LogMessage(/* ... */); }


I know this seems like an irrelevant suggestion, but simple changes like this can go a long way for future maintainability.

Code Snippets

public interface ILogger
{
    void LogMessage(string message, params Object[] args);
}

public class ConsoleLogger : ILogger
{
    public void LogMessage(string message, params Object[] args)
    {
        Console.WriteLine(string.Format(message, args));
    }
}
public class EventLogger : ILogger
{
    // ...
}
private ILogger _Logger;

public ClassName(ILogger logger)
{
    _Logger = logger;
}
logger.LogMessage(/* ... */);
if (logger != null) { logger.LogMessage(/* ... */); }

Context

StackExchange Code Review Q#97872, answer score: 12

Revisions (0)

No revisions yet.