Dapatkan nama file dari string URI di C #


206

Saya memiliki metode ini untuk mengambil nama file dari string URI. Apa yang bisa saya lakukan untuk membuatnya lebih kuat?

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

Jawaban:


388

Anda bisa membuat objek System.Uri, dan menggunakan IsFile untuk memverifikasi itu file, lalu Uri.LocalPath untuk mengekstrak nama file.

Ini jauh lebih aman, karena memberi Anda cara untuk memeriksa validitas URI juga.


Edit dalam menanggapi komentar:

Untuk mendapatkan nama file lengkap, saya akan menggunakan:

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

Ini melakukan semua pengecekan kesalahan untuk Anda, dan platform-netral. Semua kasus khusus ditangani untuk Anda dengan cepat dan mudah.


Saya setuju, Anda harus benar-benar menggunakan kelas Uri karena sudah melakukan hal ini untuk Anda. +1
Dokter Jones

2
Benar, tapi saya hanya perlu nama file, bukan path file lengkap. Bukankah saya masih harus melakukan langkah itu di Uri.LocalPath?
paulwhit

2
@ paulwhit: Dalam hal ini, Anda harus menggunakan Path.GetFileName pada hasil Uri.LocalPath. Ini adalah cara penanganan yang sangat aman dan sangat teruji. Saya akan mengedit jawaban saya untuk memasukkan ini. Lihat: msdn.microsoft.com/en-us/library/…
Reed Copsey

49
isFile tampaknya hanya melihat skema. Jadi: " www / myFile.jpg " mengembalikan false, "file: //www/something.jpg" mengembalikan true, jadi tidak ada gunanya dalam kasus ini.
dethSwatch

6
Waspadalah terhadap querystring. http://www.test.com/file1.txt?a=bakan menghasilkanfile1.txt?a=b
Julian

76

Uri.IsFile tidak berfungsi dengan url http. Ini hanya berfungsi untuk "file: //". Dari MSDN : "Properti IsFile benar ketika properti Scheme sama dengan UriSchemeFile." Jadi Anda tidak bisa bergantung pada itu.

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

Uri.LocalPath melakukan konversi khusus Windows dan tidak berfungsi dengan benar di lingkungan non-Windows. Lihat jawaban saya di bawah ini untuk cara portabel untuk melakukan ini.
Kostub Deshmukh

Meskipun Anda tidak dapat menggunakan Uri.IsFileuntuk menguji pada URL http / skema, Anda dapat berhasil mengekstrak nama file dari URL http menggunakanSystem.IO.Path.GetFileName(url);
Alex Pandrea

50

Sebagian besar jawaban lain tidak lengkap atau tidak berurusan dengan hal-hal yang muncul setelah jalur (string kueri / 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);
}

Hasil tes:

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/");              // ""

7
Mengapa GetFileNameFromUrl("test")menghasilkan "test.xml" Atau itu hanya salah ketik?
ckittel

27

Jawaban yang diterima bermasalah untuk url http. Selain itu Uri.LocalPathmelakukan konversi khusus Windows, dan ketika seseorang menunjukkan meninggalkan string kueri di sana. Cara yang lebih baik adalah menggunakanUri.AbsolutePath

Cara yang benar untuk melakukan ini untuk url http adalah:

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

7
Perhatikan bahwa untuk URL yang lolos seperti http://example.com/dir/hello%20world.txtini akan kembali hello%20world.txtsedangkan Uri.LocalPathpendekatannya akan kembalihello world.txt
Jeff Moser

22

Saya pikir ini akan melakukan apa yang Anda butuhkan:

var uri = new Uri(hreflink);
var filename = uri.Segments.Last();

2
Ini memang terlihat seperti solusi yang elegan, tetapi perlu diingat ini hanya bekerja pada URI absolut dan mengembalikan nilai yang dikodekan / lolos (gunakan Uri.UnescapeDataString()untuk mengubah% 20 dan + ke spasi).
Ronald

8
using System.IO;

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

Ini mengasumsikan, tentu saja, bahwa Anda telah menguraikan nama file.

EDIT # 2:

using System.IO;

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

Ini harus menangani spasi dan sejenisnya dalam nama file.


3
Colon tidak dapat diterima di jalur di semua platform, jadi peretasan seperti ini mungkin gagal, katakanlah, Mono.NET berjalan pada varian * nix. Lebih baik menggunakan System.Uri karena dirancang khusus untuk melakukan apa yang dibutuhkan OP.
richardtallent

1
Poin yang valid! Saya selalu melupakan Mono. Saya berpikir tentang ruang dan sejenisnya, tetapi tidak pada titik dua.
Mike Hofer

2

ini adalah sampel saya yang dapat Anda gunakan:

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

Pemakaian:

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

0

Sederhana dan lurus ke depan:

            Uri uri = new Uri(documentAttachment.DocumentAttachment.PreSignedUrl);
            fileName = Path.GetFileName(uri.LocalPath);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.