• Stars
    star
    1,315
  • Rank 35,778 (Top 0.8 %)
  • Language
    C#
  • License
    MIT License
  • Created over 4 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Fast, cross-platform and reliable multipart downloader with asynchronous progress events for .NET applications.

Windows x64 Ubuntu x64 codecov NuGet NuGet CodeFactor Codacy Badge License Generic badge Generic badge Generic badge

Downloader

πŸš€ Fast, cross-platform and reliable multipart downloader with .Net Core supporting πŸš€

Downloader is a modern, fluent, asynchronous, testable and portable library for .NET. This is a multipart downloader with asynchronous progress events. This library can be added to your .Net Core v2 and later or .Net Framework v4.5 or later projects.

Downloader is compatible with .NET Standard 2.0 and above, running on Windows, Linux, and macOS, in full .NET Framework or .NET Core.

For a complete example see Downloader.Sample project from this repository.

Sample Console Application

sample-project

Features at a glance

  • Simple interface to make download requests.
  • Download files async and non-blocking.
  • Download any file like image, video, pdf, apk, etc.
  • Cross-platform library to download any files of any size.
  • Get real-time progress info on each block.
  • Download file multipart as parallel.
  • Handle all the client-side and server-side exceptions non-stopping.
  • Config your ChunkCount to define the parts count of the download file.
  • Download file multipart as in-memory or on-disk mode.
  • Chunks are saved in parallel on the final file, not the temp files.
  • The file size is pre-allocated before the download starts.
  • Store the download package object to resume the download when you want.
  • Get download speed or progress percentage in each progress event.
  • Get download progress events per chunk downloads.
  • Fast Pause and Resume download asynchronously.
  • Stop and Resume downloads whenever you want with the package object.
  • Supports large file download.
  • Set a dynamic speed limit on downloads (changeable speed limitation on the go).
  • Download files without storing them on disk and get a memory stream for each downloaded file.
  • Serializable download package (to/from JSON or Binary)
  • Live streaming support, suitable for playing music at the same time as downloading.
  • Ability to download just a certain range of bytes of a large file.
  • Code is tiny, fast and does not depend on external libraries.
  • Control the amount of system memory (RAM) the Downloader consumes during downloading.

Installing via NuGet

PM> Install-Package Downloader

Installing via the .NET Core command line interface

dotnet add package Downloader

How to use

Step 1: Create your custom configuration

Simple Configuration

var downloadOpt = new DownloadConfiguration()
{
    ChunkCount = 8, // file parts to download, the default value is 1
    ParallelDownload = true // download parts of the file as parallel or not. The default value is false
};

Complex Configuration

Note: Do not use all of the below options in your applications, just add which one you need.

var downloadOpt = new DownloadConfiguration()
{
    // usually, hosts support max to 8000 bytes, default value is 8000
    BufferBlockSize = 10240,
    // file parts to download, the default value is 1
    ChunkCount = 8,             
    // download speed limited to 2MB/s, default values is zero or unlimited
    MaximumBytesPerSecond = 1024*1024*2, 
    // the maximum number of times to fail
    MaxTryAgainOnFailover = 5,    
    // release memory buffer after each 50 MB
    MaximumMemoryBufferBytes = 1024 * 1024 * 50, 
    // download parts of the file as parallel or not. The default value is false
    ParallelDownload = true,
    // number of parallel downloads. The default value is the same as the chunk count
    ParallelCount = 4,    
    // timeout (millisecond) per stream block reader, default values is 1000
    Timeout = 1000,      
    // set true if you want to download just a specific range of bytes of a large file
    RangeDownload = false,
    // floor offset of download range of a large file
    RangeLow = 0,
    // ceiling offset of download range of a large file
    RangeHigh = 0, 
    // clear package chunks data when download completed with failure, default value is false
    ClearPackageOnCompletionWithFailure = true, 
    // minimum size of chunking to download a file in multiple parts, the default value is 512
    MinimumSizeOfChunking = 1024, 
    // Before starting the download, reserve the storage space of the file as file size, the default value is false
    ReserveStorageSpaceBeforeStartingDownload = true; 
    // config and customize request headers
    RequestConfiguration = 
    {        
        Accept = "*/*",
        CookieContainer = cookies,
        Headers = new WebHeaderCollection(), // { your custom headers }
        KeepAlive = true, // default value is false
        ProtocolVersion = HttpVersion.Version11, // default value is HTTP 1.1
        UseDefaultCredentials = false,
        // your custom user agent or your_app_name/app_version.
        UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
        Proxy = new WebProxy() {
           Address = new Uri("http://YourProxyServer/proxy.pac"),
           UseDefaultCredentials = false,
           Credentials = System.Net.CredentialCache.DefaultNetworkCredentials,
           BypassProxyOnLocal = true
        }
    }
};

Step 2: Create a download service instance per download and pass your config

var downloader = new DownloadService(downloadOpt);

Step 3: Handle download events

// Provide `FileName` and `TotalBytesToReceive` at the start of each download
downloader.DownloadStarted += OnDownloadStarted;

// Provide any information about chunker downloads, 
// like progress percentage per chunk, speed, 
// total received bytes and received bytes array to live streaming.
downloader.ChunkDownloadProgressChanged += OnChunkDownloadProgressChanged;

// Provide any information about download progress, 
// like progress percentage of sum of chunks, total speed, 
// average speed, total received bytes and received bytes array 
// to live streaming.
downloader.DownloadProgressChanged += OnDownloadProgressChanged;

// Download completed event that can include errors or 
// canceled or download completed successfully.
downloader.DownloadFileCompleted += OnDownloadFileCompleted;

Step 4: Start the download with the URL and file name

string file = @"Your_Path\fileName.zip";
string url = @"https://file-examples.com/fileName.zip";
await downloader.DownloadFileTaskAsync(url, file);

Step 4b: Start the download without file name

DirectoryInfo path = new DirectoryInfo("Your_Path");
string url = @"https://file-examples.com/fileName.zip";
// download into "Your_Path\fileName.zip"
await downloader.DownloadFileTaskAsync(url, path); 

Step 4c: Download in MemoryStream

// After download completion, it gets a MemoryStream
Stream destinationStream = await downloader.DownloadFileTaskAsync(url); 

How to pause and resume downloads quickly

When you want to resume a download quickly after pausing a few seconds. You can call the Pause function of the downloader service. This way, streams stay alive and are only suspended by a locker to be released and resumed whenever you want.

// Pause the download
DownloadService.Pause();

// Resume the download
DownloadService.Resume();

How to stop and resume downloads other time

The ‍DownloadService class has a property called Package that stores each step of the download. To stop the download you must call the CancelAsync method. Now, if you want to continue again, you must call the same DownloadFileTaskAsync function with the Package parameter to resume your download. For example:

// At first, keep and store the Package file to resume 
// your download from the last download position:
DownloadPackage pack = downloader.Package;

Stop or cancel download:

// This function breaks your stream and cancels progress.
downloader.CancelAsync();

Resuming download after cancelation:

await downloader.DownloadFileTaskAsync(pack);

So that you can even save your large downloads with a very small amount in the Package and after restarting the program, restore it and start continuing your download. The packages are your snapshot of the download instance. Only the downloaded file addresses will be included in the package and you can resume it whenever you want. For more detail see StopResumeDownloadTest method

Note: Sometimes a server does not support downloading in a specific range. That time, we can't resume downloads after canceling. So, the downloader starts from the beginning.


Fluent download builder usage

For easy and fluent use of the downloader, you can use the DownloadBuilder class. Consider the following examples:

Simple usage:

await DownloadBuilder.New()
    .WithUrl(@"https://host.com/test-file.zip")
    .WithDirectory(@"C:\temp")
    .Build()
    .StartAsync();

Complex usage:

IDownload download = DownloadBuilder.New()
    .WithUrl(@"https://host.com/test-file.zip")
    .WithDirectory(@"C:\temp")
    .WithFileName("test-file.zip")
    .WithConfiguration(new DownloadConfiguration())
    .Build();

download.DownloadProgressChanged += DownloadProgressChanged;
download.DownloadFileCompleted += DownloadFileCompleted;
download.DownloadStarted += DownloadStarted;
download.ChunkDownloadProgressChanged += ChunkDownloadProgressChanged;

await download.StartAsync();

download.Stop(); // cancel current download

Resume the existing download package:

await DownloadBuilder.Build(package).StartAsync();

Resume the existing download package with a new configuration:

await DownloadBuilder.Build(package, config).StartAsync();

Pause and Resume quickly:

var download = DownloadBuilder.New()
     .Build()
     .WithUrl(url)
     .WithFileLocation(path);
await download.StartAsync();

download.Pause(); // pause current download quickly

download.Resume(); // continue current download quickly

When does the Downloader fail to download in multiple chunks?

Content-Length:

If your URL server does not provide the file size in the response header (Content-Length). The Downloader cannot split the file into multiple parts and continues its work with one chunk.

Accept-Ranges:

If the server returns Accept-Ranges: none in the responses header then that means the server does not support download in range and the Downloader cannot use multiple chunking and continues its work with one chunk.

Content-Range:

At first, the Downloader sends a GET request to the server to fetch the file's size in the range. If the server does not provide Content-Range in the header then that means the server does not support download in range. Therefore, the Downloader has to continue its work with one chunk.


How to serialize and deserialize the downloader package

What is Serialization?

Serialization is the process of converting an object's state into information that can be stored for later retrieval or that can be sent to another system. For example, you may have an object that represents a document that you wish to save. This object could be serialized to a stream of binary information and stored as a file on disk. Later the binary data can be retrieved from the file and deserialized into objects that are exact copies of the original information. As a second example, you may have an object containing the details of a transaction that you wish to send to another type of system. This information could be serialized to XML before being transmitted. The receiving system would convert the XML into a format that it could understand.

In this section, we want to show how to serialize download packages to JSON text or Binary, after stopping the download to keep downloading data and resuming that every time you want. You can serialize packages even using memory storage for caching download data which is used MemoryStream.

JSON Serialization

Serializing the package to JSON is very simple like this:

var packageJson = JsonConvert.SerializeObject(package);

Deserializing into the new package:

var newPack = JsonConvert.DeserializeObject<DownloadPackage>(packageJson);

For more detail see PackageSerializationTest method

Binary Serialization

To serialize or deserialize the package into a binary file, first, you need to serialize it to JSON and next save it with BinaryWriter.

NOTE: The BinaryFormatter type is dangerous and is not recommended for data processing. Applications should stop using BinaryFormatter as soon as possible, even if they believe the data they're processing to be trustworthy. BinaryFormatter is insecure and can't be made secure. So, BinaryFormatter is deprecated and we can no longer support it. Reference

Instructions for Contributing

Welcome to contribute, feel free to change and open a PullRequest to develop the branch. You can use either the latest version of Visual Studio or Visual Studio Code and .NET CLI for Windows, Mac and Linux.

For GitHub workflow, check out our Git workflow below this paragraph. We are following the excellent GitHub Flow process, and would like to make sure you have all of the information needed to be a world-class contributor!

Git Workflow

The general process for working with Downloader is:

  1. Fork on GitHub
  2. Make sure your line endings are correctly configured and fix your line endings!
  3. Clone your fork locally
  4. Configure the upstream repo (git remote add upstream git://github.com/bezzad/downloader)
  5. Switch to the latest development branch (eg vX.Y.Z, using git checkout vX.Y.Z)
  6. Create a local branch from that (git checkout -b myBranch).
  7. Work on your feature
  8. Rebase if required
  9. Push the branch up to GitHub (git push origin myBranch)
  10. Send a Pull Request on GitHub - the PR should target (have as a base branch) the latest development branch (eg vX.Y.Z) rather than master.

We accept pull requests from the community. But, you should never work on a clone of the master, and you should never send a pull request from the master - always from a branch. Please be sure to branch from the head of the latest vX.Y.Z develop branch (rather than master) when developing contributions.

You can run tests with the Docker Compose file with the following command:

docker-compose -p downloader up

Or with docker file:

docker build -f ./dockerfile -t downloader-linux . docker run --name downloader-linux-container -d downloader-linux --env=ASPNETCORE_ENVIRONMENT=Development .

Or run the following command to call docker directly:

docker run --rm -v ${pwd}:/app --env=ASPNETCORE_ENVIRONMENT=Development -w /app/tests mcr.microsoft.com/dotnet/sdk:6.0 dotnet test ../ --logger:trx

License

Licensed under the terms of the MIT License

FOSSA Status

Contributors

Thanks go to these wonderful people (List made with contrib.rocks):

More Repositories

1

PdfiumViewer

PDF viewer based on Google's PDFium port to .Net Core.
C#
123
star
2

foobar.withgoogle

My Google Foo Bar Challenges
Python
56
star
3

BlurMessageBox

The MessageBox for WPF and WinForms application by the ability to blurring that parent form
C#
43
star
4

AntiDebugging

.Net Framweork and .Net Core Anti Debugging to stop multiple malicious tools and hooks on your software.
C#
37
star
5

MakeClassSchedule

Make university class schedule by Parallel Genetic Algorithm in C# WinForm
HTML
33
star
6

TSP-GA

Traveling Salesman Problem Using Parallel Genetic Algorithms
C#
32
star
7

SecureChat

Node.js based, client side asymmetric encrypted instant chat channel
JavaScript
31
star
8

ErrorControlSystem

ErrorControlSystem is a .NET library created to automate handling .NET Windows-Base application exceptions and raise that to a sql server. This exception handler have some features as screen capturing, fetch server date time in exception occurrence time and etc.
C#
30
star
9

MP3Player

Simple MP3 Player was taken from the large NAudio library
C#
22
star
10

StringComparison

String Comparision in C#.NET
C#
20
star
11

WHOis

Whois Online Domain Database for check domains are reserved or not as parallel
C#
18
star
12

UltraDataGridView

A Win32 DataGridView by columns filtering features.
C#
18
star
13

MouseKeyboardActivityMonitor

This library attaches to windows global hooks, tracks keyboard and mouse clicks and movement and raises common .NET events with KeyEventArgs and MouseEventArgs.
C#
17
star
14

TeleBotMessenger

Send message to telegram channels or groups by telegram bots
C#
14
star
15

InMemory

A MemoryCache which tries to prevent cache miss for hot entries, by refreshing before expiration.
C#
14
star
16

TaskScheduler

Dynamic Task Scheduler as windows service
C#
12
star
17

TextViewer

WPF canvas as text viewer like FlowDocument by more features like lines and word selection.
C#
11
star
18

HybridRedisCache

Hybrid cache uses both IMemoryCache and Redis in C#
C#
11
star
19

CaptchaGenerator

.Net cross-platform captcha generator with SixLabors library on .NET Core
C#
11
star
20

MEF-Sample

Sample of Managed Extensibility Framework (MEF)
10
star
21

SnippingMultipleScreen

Snipping Multiple Screen is a WPF application to capture many screen shot and merging that's to a picture and save it for you on Windows.
C#
10
star
22

NotifyIcon

NotifyIcon (aka system tray icon or taskbar icon) for the WPF platform. (Support .Net Core 3.1+)
C#
9
star
23

Clean-Code-Presentation

This is an introductory presentation on Clean Code inspired by Robert C. Martin's book by the Same Title.
9
star
24

HintTextBox

A TextBox by default value to hint that and have some features such as Math Parser, Numeric Mode, Thousands Separator and etc.
C#
9
star
25

UnitJest

Automation generate unit test for JavaScript by Jest Framework
JavaScript
8
star
26

VirtualizingWrapPanel

Implementation of a VirtualizingWrapPanel for WPF
C#
8
star
27

ServiceLifeController

Control windows services by monitoring and service stopping alert
C#
8
star
28

NFA2DFA

NFA2DFA is a win32 application for convert a nondeterministic finite state automaton (NFA) to a deterministic finite state automaton (DFA).
C#
7
star
29

FirebaseCloudMessaging

FCM (Firebase Cloud Messaging) sample for multiple clients and cross platform by C#.NET Core 2
HTML
7
star
30

SlackMessenger

A .NET library to enable you to send bot messages in slack
C#
7
star
31

AnimatingTilePanel

WPF panel control by animating items in resize or moving
C#
6
star
32

MetroWindow

WPF light Metro Window
C#
6
star
33

BlackANT

Black ANT Trojan
C#
6
star
34

FileParallelWrite

Writing To a File With Multiple Streams C#
C#
6
star
35

EmailServiceSample

.NET Email Service Sample by SMTP
C#
6
star
36

SignalR

A reusable win32 API for connect any client to server or each other clients. Send data or code from one client to other clients included.
C#
6
star
37

WpfMagnifier

Magnifier control sample in WPF
C#
5
star
38

NasaAntsSimulation

Csharp Simulation for NASA ANTS project
C#
5
star
39

RedisCache.NetDemo

Caching on Redis with .Net 6 sample project
C#
5
star
40

TinyMediator

A light weight copy of MediatR for Mediator Pattern in .NetStandard
C#
5
star
41

Enigma

The Enigma machine is an encryption algorithm
C#
5
star
42

CoolNameGenerator

Generate Cool Name by Parallel Genetic Algorithm. Best way to product website domain name and etc.
C#
4
star
43

CalibrePlugins

Some plugions for the Calibre application.
Python
4
star
44

SeekBar

SeekBar control for WPF
C#
4
star
45

SecureFolder

SecureFolder is a Cross-Platform application to encrypt and decrypt all files of a directory on which the application executed.
C#
4
star
46

SaleOnlineReporter

Sale Distribute online reporter in ASP.NET MVC for sale main application
JavaScript
4
star
47

ClearFilesPermission

Clear all files and folders permissions of a directory in windows (32/64 bit)
C#
4
star
48

Room-3D

The 3D Room designed in DirectX by full effective subjects.
RPC
4
star
49

ExCryptography

Encryption and decryption by symmetric and hashing algorithms
C#
4
star
50

WpfGrowlNotification

Lightweight growl notifications for WPF project.
C#
4
star
51

AutoVersionUpdater

.NET Applications Auto Version Updater
Batchfile
4
star
52

Alloy-DiagramBuilder-MVC

Alloy DiagramBuilder is a framework built on top of YUI3 (JavaScript) that uses Bootstrap 3 (HTML/CSS) to provide a simple API for building high scalable applications
JavaScript
4
star
53

MotionDetection

Cross-Platform Motion Detection app
C#
3
star
54

Simple-broadcast-chat-nodejs-socket.io

Build a simple chat app with node.js and socket.io
JavaScript
3
star
55

CameraStreamer

Stream a Raspberry Pi Camera from web socket
JavaScript
3
star
56

N-Queen-GA

Solve N-Queen problem by GA in JavaScript
JavaScript
3
star
57

FlowParagraphToLines

Find best stable way to convert WPF flow document paragraph test to lines (string array)
C#
3
star
58

OrangePersonalWebsite

Xomorod.com website template by asp.net.
CSS
3
star
59

AnnotationControl

Wpf Annotation control which inherited from Decorator control
C#
3
star
60

IPGA

Image Processing by Genetic Algorithm
C#
3
star
61

Museum-3D

The 3D Museum designed by DirectX
RPC
3
star
62

Xomorod.com

The Xomorod Corporation official website
HTML
3
star
63

WebUITestSample

A test for web UI by Protractor and Puppeteer
JavaScript
3
star
64

GoProject

GoProject is GoJS libs for ASP.NET MVC platform. GoJS is a JavaScript library for implementing interactive diagrams.
JavaScript
3
star
65

Chess

C# Chess Game that enables a user to play chess against the computer. Developed using C# (C Sharp) and the Microsoft DotNet framework.
C#
3
star
66

PiCompress

Compress and optimize JPEG and PNG images by using Tinify API of TinyPNG.com
C#
3
star
67

SQLiteEncryption

SQLite Encryption using Entity Framework Core (EFCore)
3
star
68

StateDesignPatternSample

The State design pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.
C#
3
star
69

KeepOnMemory

Keep any files fly on the RAM (as memory stream) and restore it on any other storage devices without use any interface storage devices like local hard disk.
C#
3
star
70

Progress

Cross platform shell ProgressBar for Linux, Windows, OSX with dot net core
C#
3
star
71

AdoManager

ADO.NET connection manager to store OOP connection string and execute a query easily.
C#
3
star
72

CordovaNativeDroid2

nativeDroid2 is a theme for jQuery Mobile inspired by material design and a successor of nativeDroid and implemented in Apache Cordova platforms.
CSS
2
star
73

Sudoku

Sudoku 9Γ—9 puzzle application designed in C# winForm
C#
2
star
74

CamVideoCapture

Camera Video Capture by C#
C#
2
star
75

OwinSelfHostWebSiteSample

Asp.NET Website by Owin Self Host
C#
2
star
76

LeetCode

My Solutions to LeetCode Problems
JavaScript
2
star
77

MotionAlarm

Motion Alarm codes in Matlab
HTML
2
star
78

Whois.Core

Whois web application for search multiple domain names in parallel mode
HTML
2
star
79

bezzad

my Github profile
2
star
80

DynamicMVC-Sample

A sample of ASP.NET MVC 4 by Dynamic Model and dynamic grid of that model.
C#
2
star
81

Process-Scheduling

Process Scheduling simulator for SPN, Round Robin, FCFS algorithms
C#
2
star
82

MultiForm-Application

One application for manage multiple plugin form which any form is a single application.
C#
2
star
83

School-Website

School Website by MVC
C#
2
star
84

WordFixer

Find and replace words by regular expression on a big file
C#
2
star
85

RemovePixels

A WPF application to remove (transparent) any pixels of image which is upper or lower than a threshold.
C#
2
star
86

DecoratorSample

Decorator design pattern on notification sample
C#
2
star
87

FoxRabbit

Fox Rabbit implemented by Fuzzy Logic algorithm
C#
2
star
88

WpfUIControls

Some UserControls for WPF .NET
C#
2
star
89

DotNetAppMemorySize

Get .Net application real memory size
C#
2
star
90

AdvTreeView

A control inherited from windows TreeView control's by 3 state checkbox feature.
Visual Basic
2
star
91

TicTacToe

Tic Tac Toe puzzle application, designed in C# WinForm
C#
2
star
92

PingServer

Ping an address in a periodic time to know your internet is on or off. Or for another ping jobs...
C#
2
star
93

SampleMVVM

A WPF MVVM patttern sample which implemented by Fody
C#
1
star
94

ArrowTabs-v2

Arrow Tabs v2 using jQuery
HTML
1
star
95

SwashbuckleSample

Web API Help page by Swashbuckle auto document generator
C#
1
star
96

Hoaxify

Personal web application based on Node.js and Express.js
JavaScript
1
star
97

MvcDropDownSample

Mvc DropDown Sample
C#
1
star
98

TeleBanel

Website panel controller by Telegram Bots
Smalltalk
1
star
99

CreateNCharWords

Create all N characters word by .Net console
C#
1
star
100

RealmSample

A sample of Realm database in .NET Core by MVVM pattern
C#
1
star