J'ai cette méthode pour récupérer le nom du fichier à partir d'une chaîne URI. Que puis-je faire pour le rendre plus robuste?
private string GetFileName(string hrefLink)
{
string[] parts = hrefLink.Split('/');
string fileName = "";
if (parts.Length > 0)
fileName = parts[parts.Length - 1];
else
fileName = hrefLink;
return fileName;
}
Vous pouvez simplement créer un objet System.Uri et utiliser IsFile pour vérifier que c'est un fichier, puis ri.LocalPath pour extraire le nom du fichier.
C'est beaucoup plus sûr, car cela vous permet également de vérifier la validité de l'URI.
Modifier en réponse au commentaire:
Pour obtenir uniquement le nom de fichier complet, je voudrais utiliser:
Uri uri = new Uri(hreflink);
if (uri.IsFile) {
string filename = System.IO.Path.GetFileName(uri.LocalPath);
}
Ceci effectue toutes les erreurs de vérification pour vous et est indépendant de la plate-forme. Tous les cas spéciaux sont traités rapidement et facilement pour vous.
Uri.IsFile ne fonctionne pas avec les URL http. Cela ne fonctionne que pour "fichier: //". From MSDN : "La propriété IsFile est true lorsque la propriété Scheme est égale à UriSchemeFile." Donc, vous ne pouvez pas compter sur cela.
Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.LocalPath);
La plupart des autres réponses sont incomplètes ou ne traitent pas d'éléments venant après le chemin (chaîne de requête/hash).
readonly static Uri SomeBaseUri = new Uri("http://canbeanything");
static string GetFileNameFromUrl(string url)
{
Uri uri;
if (!Uri.TryCreate(url, UriKind.Absolute, out uri))
uri = new Uri(SomeBaseUri, url);
return Path.GetFileName(uri.LocalPath);
}
Résultats de test:
GetFileNameFromUrl(""); // ""
GetFileNameFromUrl("test"); // "test"
GetFileNameFromUrl("test.xml"); // "test.xml"
GetFileNameFromUrl("/test.xml"); // "test.xml"
GetFileNameFromUrl("/test.xml?q=1"); // "test.xml"
GetFileNameFromUrl("/test.xml?q=1&x=3"); // "test.xml"
GetFileNameFromUrl("test.xml?q=1&x=3"); // "test.xml"
GetFileNameFromUrl("http://www.a.com/test.xml?q=1&x=3"); // "test.xml"
GetFileNameFromUrl("http://www.a.com/test.xml?q=1&x=3#aidjsf"); // "test.xml"
GetFileNameFromUrl("http://www.a.com/a/b/c/d"); // "d"
GetFileNameFromUrl("http://www.a.com/a/b/c/d/e/"); // ""
La réponse acceptée est problématique pour les URL http. De plus, Uri.LocalPath
effectue des conversions spécifiques à Windows et, comme quelqu'un l'a souligné, laisse des chaînes de requête à l'intérieur. Une meilleure façon consiste à utiliser Uri.AbsolutePath
La bonne façon de faire cela pour les URL http est:
_Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.AbsolutePath);
_
Je pense que cela fera ce dont vous avez besoin:
var uri = new Uri(hreflink);
var filename = uri.Segments.Last();
using System.IO;
private String GetFileName(String hrefLink)
{
return Path.GetFileName(hrefLink.Replace("/", "\\"));
}
Cela suppose, bien entendu, que vous ayez analysé le nom du fichier.
EDIT # 2:
using System.IO;
private String GetFileName(String hrefLink)
{
return Path.GetFileName(Uri.UnescapeDataString(hrefLink).Replace("/", "\\"));
}
Cela devrait gérer les espaces et autres dans le nom du fichier.
voici mon exemple que vous pouvez utiliser:
public static string GetFileNameValidChar(string fileName)
{
foreach (var item in System.IO.Path.GetInvalidFileNameChars())
{
fileName = fileName.Replace(item.ToString(), "");
}
return fileName;
}
public static string GetFileNameFromUrl(string url)
{
string fileName = "";
if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
{
fileName = GetFileNameValidChar(Path.GetFileName(uri.AbsolutePath));
}
string ext = "";
if (!string.IsNullOrEmpty(fileName))
{
ext = Path.GetExtension(fileName);
if (string.IsNullOrEmpty(ext))
ext = ".html";
else
ext = "";
return GetFileNameValidChar(fileName + ext);
}
fileName = Path.GetFileName(url);
if (string.IsNullOrEmpty(fileName))
{
fileName = "noName";
}
ext = Path.GetExtension(fileName);
if (string.IsNullOrEmpty(ext))
ext = ".html";
else
ext = "";
fileName = fileName + ext;
if (!fileName.StartsWith("?"))
fileName = fileName.Split('?').FirstOrDefault();
fileName = fileName.Split('&').LastOrDefault().Split('=').LastOrDefault();
return GetFileNameValidChar(fileName);
}
Usage:
var fileName = GetFileNameFromUrl("http://cdn.p30download.com/?b=p30dl-software&f=Mozilla.Firefox.v58.0.x86_p30download.com.Zip");