web-dev-qa-db-ja.com

C#のURI文字列からファイル名を取得する

文字列URIからファイル名を取得するためのこのメソッドがあります。より堅牢にするために何ができますか?

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;
}
183
paulwhit

System.Uriオブジェクトを作成し、IsFileを使用してそれがファイルであることを確認してから、 ri.LocalPath でファイル名を抽出できます。

これは、URIの有効性もチェックする手段を提供するため、はるかに安全です。


コメントに応じて編集:

完全なファイル名だけを取得するには、次を使用します。

Uri uri = new Uri(hreflink);
if (uri.IsFile) {
    string filename = System.IO.Path.GetFileName(uri.LocalPath);
}

これはすべてのエラーチェックを行い、プラットフォームに依存しません。特殊なケースはすべて、迅速かつ簡単に処理されます。

361
Reed Copsey

Uri.IsFileはhttp URLでは機能しません。 「file://」に対してのみ機能します。 From MSDN : "SchemeプロパティがUriSchemeFileと等しい場合、IsFileプロパティはtrueです。"だから、それに頼ることはできません。

Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.LocalPath);
67
Le Zhang

ほとんどの答えは不完全であるか、パスの後に来るもの(クエリ文字列/ハッシュ)を処理しません。

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);
}

試験結果:

GetFileNameFromUrl("");                                         // ""
GetFileNameFromUrl("test");                                     // "test.xml"
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/");              // ""
35
Ronnie Overby

受け入れられた回答は、http URLに対して問題があります。さらに Uri.LocalPath はWindows固有の変換を行い、誰かが指摘したようにクエリ文字列をそこに残します。より良い方法は Uri.AbsolutePath を使用することです

HTTP URLに対してこれを行う正しい方法は次のとおりです。

Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.AbsolutePath);
22
Kostub Deshmukh

私はこれがあなたが必要とすることをするだろうと思う:

var uri = new Uri(hreflink);
var filename = uri.Segments.Last();
17
Zeus82
using System.IO;

private String GetFileName(String hrefLink)
{
    return Path.GetFileName(hrefLink.Replace("/", "\\"));
}

もちろん、これはファイル名を解析したことを前提としています。

編集#2:

using System.IO;

private String GetFileName(String hrefLink)
{
    return Path.GetFileName(Uri.UnescapeDataString(hrefLink).Replace("/", "\\"));
}

これは、ファイル名のスペースなどを処理する必要があります。

7
Mike Hofer

これはあなたが使用できる私のサンプルです:

        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);
    }

使用法:

var fileName = GetFileNameFromUrl("http://cdn.p30download.com/?b=p30dl-software&f=Mozilla.Firefox.v58.0.x86_p30download.com.Zip");
2
Ali Yousefi