我目前正在编写一个下载管理器,它具有从剪贴板添加链接的功能。
现在我需要编写一个方法来查找链接中文件的文件名,例如 输出文件名的方法: “https://example.com/document.doc”输出“document.doc” “https://example.com/document.doc?smth=123”输出“document.doc” “https://exmaple.com/download?file=123”输出此链接后面的文件的文件名
我尝试过,但我只适用于第一个链接:
string[] uriparts = i.Split('/');
string filename = uriparts[uriparts.Length - 1];
您可以使用
Uri
类来处理 URL,它将提取主机、协议、路径、查询字符串等单独的部分。然后您可以使用 Path
类来处理路径并从中提取文件名:
var url = new Uri(i);
var fileName = Path.GetFileName(url.AbsolutePath);
在大多数情况下,仅通过查看 URL 无法获取文件名。即使 URL 看起来包含实际文件名(例如
https://example.com/download/document.doc
),您也不能保证当您访问此 URL 时,您会下载 document.doc
文件。
当您导航 URL 时,实际文件名将在响应的
Content-Disposition
标头中返回。
因此,您可以尝试首先从 URL 获取它,但您应该做好准备,它可能根本不包含文件名,并且当您执行请求时,该服务器可能会返回不同的文件名。
并且,作为后备方案,您可能需要生成自己的文件名(以防服务器不返回文件名)。例如(这里我使用
MimeTypes
nuget 包在生成文件名时将 MediaType 映射到文件扩展名):
var url = new Uri(urlString);
string GenerateFileName(HttpResponseMessage response)
{
string? extension = response.Content.Headers.ContentType is { MediaType: { } mediaType }
? MimeTypes.GetMimeTypeExtensions(mediaType).FirstOrDefault()
: null;
return $"Unnamed{extension}";
}
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url);
string fileName = response.Content.Headers.ContentDisposition is { FileName: not null } disposition
? disposition.FileName
: (Path.GetFileName(url.AbsolutePath) ?? GenerateFileName(response));
}