Необязательно использовать System.Drawing
для поиска формата изображения в URI. System.Drawing
недоступен, .NET Core
если вы не загрузите пакет NuGet System.Drawing.Common, и поэтому я не вижу хороших кросс-платформенных ответов на этот вопрос.
Кроме того, мой пример не используется, System.Net.WebClient
поскольку Microsoft явно не рекомендует использоватьSystem.Net.WebClient
.
Мы не рекомендуем использовать этот WebClient
класс для новых разработок. Вместо этого используйте класс System.Net.Http.HttpClient .
Загрузите изображение и запишите его в файл, не зная расширения (кроссплатформенность) *
* Без старых System.Net.WebClient
и System.Drawing
.
Этот метод будет асинхронно загружать изображение (или любой файл, если URI имеет расширение файла) с помощью, System.Net.Http.HttpClient
а затем записывает его в файл, используя то же расширение файла, что и у изображения в URI.
Получение расширения файла
Первая часть получения расширения файла - это удаление всех ненужных частей из URI.
Мы используем Uri.GetLeftPart () с UriPartial.Path , чтобы получить все от Scheme
до к Path
.
Другими словами, https://www.example.com/image.png?query&with.dots
становится https://www.example.com/image.png
.
После этого мы используем Path.GetExtension (), чтобы получить только расширение (в моем предыдущем примере .png
).
var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
var fileExtension = Path.GetExtension(uriWithoutQuery);
Скачивание образа
Отсюда все должно быть прямо. Загрузите изображение с помощью HttpClient.GetByteArrayAsync , создайте путь, убедитесь, что каталог существует, а затем запишите байты в путь с помощью File.WriteAllBytesAsync () (или File.WriteAllBytes
если вы используете .NET Framework)
private async Task DownloadImageAsync(string directoryPath, string fileName, Uri uri)
{
using var httpClient = new HttpClient();
// Get the file extension
var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
var fileExtension = Path.GetExtension(uriWithoutQuery);
// Create file path and ensure directory exists
var path = Path.Combine(directoryPath, $"{fileName}{fileExtension}");
Directory.CreateDirectory(directoryPath);
// Download the image and write to the file
var imageBytes = await _httpClient.GetByteArrayAsync(uri);
await File.WriteAllBytesAsync(path, imageBytes);
}
Обратите внимание, что вам потребуются следующие директивы using.
using System;
using System.IO;
using System.Threading.Tasks;
using System.Net.Http;
Пример использования
var folder = "images";
var fileName = "test";
var url = "https://cdn.discordapp.com/attachments/458291463663386646/592779619212460054/Screenshot_20190624-201411.jpg?query&with.dots";
await DownloadImageAsync(folder, fileName, new Uri(url));
Ноты
- Плохая практика - создавать новый
HttpClient
для каждого вызова метода. Предполагается, что он будет повторно использован во всем приложении. Я написал короткий пример ImageDownloader
(50 строк) с дополнительной документацией, которая правильно повторно использует HttpClient
и правильно избавляется от нее, которую вы можете найти здесь .