百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
D

Downloader

> 数据库
开源

为 .NET 应用程序提供快速、跨平台且可靠的多部分下载器,具有异步进度事件。

1.7K stars0 点赞0 次浏览
访问官网GitHub

工具介绍

为 .NET 应用程序提供快速、跨平台且可靠的多部分下载器,具有异步进度事件。

# Downloader :rocket: Fast, cross-platform, and reliable multipart downloader in `.Net` :rocket: > [!TIP] > **Prefer a ready-to-use app over a library?** Meet **[Downloader Desktop](https://github.com/bezzad/Downloader.Desktop)** — a free, open-source GUI download manager for **Windows · Linux · macOS**, powered by this engine: multi-connection downloads, pause/resume, queues, scheduler, speed limits and more — with no dependencies to install.

**Downloader** is a modern, fluent, asynchronous, and portable library for .NET, built with testability in mind. It supports multipart downloads with real-time asynchronous progress events. The current `v5.x` line targets `.NET 8`, `.NET 9`, and `.NET 10`. (If you need `.NET Standard 2.1` or older runtimes such as `.NET Framework 4.6.1`, use the `v3.x` line — see the note below.) Downloader works on Windows, Linux, and macOS. > **Note**: Support for older versions of .NET was removed in Downloader `v3.2.0`. From this version onwards, only `.Net 8.0` and higher versions are supported. > If you need compatibility with older .NET versions (e.g., `.NET Framework 4.6.1`), use Downloader `v3.1.*`. > For a complete example, see the [Downloader.Sample](https://github.com/bezzad/Downloader/blob/master/src/Samples/Downloader.Sample/Program.cs) project in this repository. ## Table of Contents - [Quick Start](#quick-start) - [Sample Console Application](#sample-console-application) - [Key Features](#key-features) - [Installation via NuGet](#installation-via-nuget) - [Installation via the .NET CLI](#installation-via-the-net-cli) - [Usage](#usage) - [How to get the file name and size without downloading](#how-to-get-the-file-name-and-size-without-downloading) - [How to pause and resume downloads quickly](#how-to-pause-and-resume-downloads-quickly) - [How to stop and resume downloads (manual approach)](#how-to-stop-and-resume-downloads-manual-approach) - [How to automatically resume downloads (recommended)](#how-to-automatically-resume-downloads-recommended) - [Fluent download builder usage](#fluent-download-builder-usage) - [Using a Custom HttpClient or HttpMessageHandler](#using-a-custom-httpclient-or-httpmessagehandler) - [When does the Downloader fail to download in multiple chunks?](#when-does-the-downloader-fail-to-download-in-multiple-chunks) - [Redirects, cookies, and protected links](#redirects-cookies-and-protected-links) - [How to serialize and deserialize the downloader package](#how-to-serialize-and-deserialize-the-downloader-package) - [Building a Native AOT Version](#-building-a-native-aot-version) - [Instructions for Contributing](#instructions-for-contributing) - [Support the Project](#support-the-project) - [License](#license) - [Contributors](#contributors) ## Quick Start ```bash dotnet add package Downloader ``` ```csharp await DownloadBuilder .New() .WithUrl(@"https://host.com/test-file.zip") .WithDirectory(@"C:\temp") .Build() .StartAsync(); ``` ## Sample Console Application --- ## Key Features - Simple interface for download requests. - Asynchronous, non-blocking file downloads. - Supports all file types (e.g., images, videos, PDFs, APKs). - Cross-platform support for files of any size. - Real-time progress updates for each download chunk. - Downloads files in multiple parts (parallel download). - Resilient to client-side and server-side errors. - Configurable `ChunkCount` to control download segmentation. - Supports both in-memory and on-disk multipart downloads. - Parallel saving of chunks directly into the final file (no temporary files). - Always downloads to a temporary file (configurable extension, default `.download`), then renames to the final name on completion. - Always pre-allocates file size before download begins. - Resume downloads manually by saving and restoring the `DownloadPackage` object. - Automatic resume: when enabled, download metadata is embedded inside the `.download` file — no extra files or manual serialization needed. - Provides real-time speed and progress data. - Asynchronous pause and resume functionality. - Download files with dynamic speed limits. - Supports downloading to memory streams (without saving to disk). - Supports large file downloads and live-streaming (e.g., music playback during download). - Download a specific byte range from a large file. - Resolve a remote file's name, size, and range support **without downloading it** (`RemoteFileResolver`). - Lightweight, fast codebase with no external dependencies. - Manage RAM usage during downloads. - Supports custom `HttpClient` or `HttpMessageHandler` injection for advanced scenarios (e.g., `IHttpClientFactory`, HTTP caching, custom delegating handlers). --- ## Installation via [NuGet](https://www.nuget.org/packages/downloader) ```text PM> Install-Package Downloader ``` ## Installation via the .NET CLI ```bash dotnet add package Downloader ``` --- ## Usage ### **Step 1**: Create a Custom Configuration #### Simple Configuration ```csharp var downloadOpt = new DownloadConfiguration() { // Number of file parts, default is 1 ChunkCount = 8, // Download parts in parallel (default is false) ParallelDownload = true }; ``` #### Complex Configuration > **Note**: Only include the options you need in your application. ``` … ``` ### Recommended setup for fast **and** reliable downloads A good general-purpose starting point — parallel for speed, with retries and auto-resume for safety: ``` … ``` > **Tip:** Higher `ChunkCount`/`ParallelCount` is not always faster — many servers rate-limit or > cap connections per client. Values around `8` chunks and `4` parallel connections are a safe, > fast default; tune for your target hosts. ### **Step 2**: Create the Download Service ```csharp var downloader = new DownloadService(downloadOpt); ``` ### **Step 3**: Handle Download Events ``` … ``` Example handler implementations: ``` … ``` > ### ⚠️ Important: how failures and cancellations are reported > > `DownloadFileTaskAsync(...)` / `StartAsync(...)` **do not throw** when a download fails or is > cancelled. The awaited call completes normally, and the outcome is delivered through the > **`DownloadFileCompleted`** event: > > - **Success** → `e.Cancelled == false` **and** `e.Error == null` > - **Failure** → `e.Error` contains the exception (e.g. a network error, or an > `IncompleteDownloadException` if the server ended the stream early) > - **Stopped/paused by you** → `e.Cancelled == true` > > Always subscribe to `DownloadFileCompleted` and check `e.Error` before treating the file as > complete — relying only on the `await` returning will silently miss failed downloads. You can > also inspect `downloader.Package.Status` (`Completed` / `Stopped` / `Failed`). ### **Step 4**: Start the Download ```csharp 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 a file name ```csharp 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 ```csharp // After the download completes, you get a MemoryStream Stream destinationStream = await downloader.DownloadFileTaskAsync(url); ``` --- ### How to get the **file name and size without downloading** Sometimes you need a remote file's name and size **before** (or without ever) downloading it — for example to populate a list/grid of queued downloads with their names and sizes while they wait for a slot, instead of starting and immediately stopping a real download just to read the headers. Use `RemoteFileResolver`. It performs a single lightweight header probe (a `Range: 0-0` GET that follows redirects) and resolves the file name exactly the way the downloader does internally — from the `Content-Disposition` header, falling back to the URL path, and finally to a generated GUID — plus the size (`Content-Range` → `Content-Length`) and whether the server supports ranged (resumable) downloads. ```csharp // Just the file name // (resilient: falls back to the URL-derived name // on a network/server error) string fileName = await RemoteFileResolver.GetFileNameAsync(url); // Full metadata in one probe: RemoteFileInfo info = await RemoteFileResolver.GetFileInfoAsync(url); Console.WriteLine($"{info.FileName} — {info.FileSize} bytes, range: {info.SupportsRange}"); // info.Address is the final URL after any redirects. ``` Both methods accept an optional `DownloadConfiguration` (to reuse your headers, proxy, credentials, cookies, redirect policy, …) and a `CancellationToken`. Each call owns and disposes its own client, so when resolving many URLs at once add your own concurrency limiting / timeouts. If you already hold a download service, the same lookup is available on it (using that service's configuration, without disturbing any download in progress): ```csharp RemoteFileInfo info = await downloader.GetFileInfoAsync(url); ``` > **Note:** `FileSize` is `-1` when the server does not advertise a length. `GetFileNameAsync` and > the service/`GetFileInfoAsync` previews are best-effort and won't throw on a server that hides its > size — you still get a usable name. --- ### How to **pause** and **resume** downloads quickly When you want to resume a download quickly after pausing for a few seconds, call the `Pause` function of the downloader service. This way, the streams stay alive and are only suspended by a lock, to be released and resumed whenever you want. ```csharp // Pause the download downloader.Pause(); // Resume the download downloader.Resume(); ``` --- ### How to **stop** and **resume** downloads (manual approach) The `DownloadService` class has a property called `Package` that holds a live snapshot of the download state (chunk positions, URL, file path, etc.). While the download is in progress, this object is updated continuously. To stop and later resume a download **manually**, you are responsible for keeping the `Package` object yourself — either in memory or serialized to disk. The Downloader does not store it for you in this approach. ```csharp // 1. Keep a reference to the package before or after stopping: DownloadPackage pack = downloader.Package; ``` **Stop or cancel the download:** ```csharp // Fire-and-forget cancellation (returns void): downloader.CancelAsync(); // Or await until the download has actually stopped before reading the package: await downloader.CancelTaskAsync(); ``` **Resume later — even after restarting the application:** ```csharp // Pass the same (or deserialized) package to resume from the last position: await downloader.DownloadFileTaskAsync(pack); ``` The `Package` object is lightweight — it contains only the URL, file path, and the position of each chunk (not the downloaded bytes). You can serialize it to JSON or binary (see [Serialization section](#how-to-serialize-and-deserialize-the-downloader-package)) and restore it at any time. For more details see the [StopResumeDownloadTest](https://github.com/bezzad/Downloader/blob/master/src/Downloader.Test/IntegrationTests/DownloadIntegrationTest.cs#L210) method. > **Note:** If the server does not support HTTP range requests, the download cannot be resumed and will restart from the beginning. --- ### How to **automatically resume** downloads (recommended) If you don'

GitHub Issues· 0 开放

在 GitHub 查看全部

暂无开放 Issues,或尚未同步最近议题。

核心特点

  • •Quick Start
  • •Sample Console Application
  • •Key Features
  • •Installation via NuGet
  • •Installation via the .NET CLI
  • •How to get the file name and size without downloading
  • •How to pause and resume downloads quickly
  • •How to stop and resume downloads (manual approach)
  • •How to automatically resume downloads (recommended)
  • •Fluent download builder usage

> 标签

C#cross-platformcsharpdotnetdotnet-core

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类数据库
定价开源

> 相关工具

P
PostgreSQL
功能强大的开源关系型数据库
R
Redis
内存数据结构存储,常用作缓存与队列
M
MySQL
广泛使用的开源关系型数据库