Nhận tên tệp từ chuỗi URI trong C #


206

Tôi có phương pháp này để lấy tên tệp từ một URI chuỗi. Tôi có thể làm gì để làm cho nó mạnh mẽ hơn?

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

Câu trả lời:


388

Bạn chỉ có thể tạo một đối tượng System.Uri và sử dụng IsFile để xác minh đó là một tệp, sau đó là Uri.LocalPath để trích xuất tên tệp.

Điều này an toàn hơn nhiều, vì nó cũng cung cấp cho bạn một phương tiện để kiểm tra tính hợp lệ của URI.


Chỉnh sửa để phản hồi bình luận:

Để chỉ lấy tên tệp đầy đủ, tôi sẽ sử dụng:

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

Điều này thực hiện tất cả các lỗi kiểm tra cho bạn và là trung lập nền tảng. Tất cả các trường hợp đặc biệt được xử lý cho bạn một cách nhanh chóng và dễ dàng.


Tôi đồng ý, bạn thực sự nên sử dụng lớp Uri vì nó đã làm điều này cho bạn. +1
Bác sĩ Jones

2
Đúng, nhưng tôi chỉ cần tên tệp chứ không phải đường dẫn tệp hoàn chỉnh. Không phải tôi vẫn còn để thực hiện bước đó trên Uri.LocalPath sao?
paulwhit

2
@paulwhit: Trong trường hợp đó, bạn nên sử dụng Path.GetFileName trên kết quả của Uri.LocalPath. Đây là một cách hoàn toàn an toàn, kiểm tra cao xử lý nó. Tôi sẽ chỉnh sửa câu trả lời của tôi để bao gồm điều này. Xem: msdn.microsoft.com/en-us/l Library / Google
Reed Copsey

49
isFile dường như chỉ nhìn vào sơ đồ. Vì vậy: " www / myFile.jpg " trả về false, "file: // www/s Something.jpg" trả về true, vì vậy nó vô dụng trong trường hợp này.
DethSwatch

6
Cũng hãy cẩn thận của một chuỗi truy vấn. http://www.test.com/file1.txt?a=bsẽ có kết quả trongfile1.txt?a=b
Julian

75

Uri.IsFile không hoạt động với http url. Nó chỉ hoạt động cho "file: //". Từ MSDN : "Thuộc tính IsFile là đúng khi thuộc tính Scheme bằng UriSchemeFile." Vì vậy, bạn không thể phụ thuộc vào điều đó.

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

Uri.LocalPath thực hiện các chuyển đổi cụ thể của Windows và không hoạt động chính xác trong môi trường không phải Windows. Xem câu trả lời của tôi dưới đây cho một cách di động để làm điều này.
Kostub Deshmukh

Mặc dù bạn không thể sử dụng Uri.IsFileđể kiểm tra URL / lược đồ http, nhưng bạn có thể trích xuất thành công tên tệp từ URL http bằng cách sử dụngSystem.IO.Path.GetFileName(url);
Alex Pandrea

50

Hầu hết các câu trả lời khác đều không đầy đủ hoặc không xử lý các nội dung đến sau đường dẫn (chuỗi truy vấn / hàm băm).

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

Kết quả kiểm tra:

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
Tại sao sẽ GetFileNameFromUrl("test")dẫn đến "test.xml" Hoặc đó chỉ là một lỗi đánh máy?
ckittel

27

Câu trả lời được chấp nhận là có vấn đề cho http url. Ngoài Uri.LocalPathra, Windows cũng chuyển đổi cụ thể và như ai đó đã chỉ ra các chuỗi truy vấn trong đó. Cách tốt hơn là sử dụngUri.AbsolutePath

Cách chính xác để làm điều này cho http url là:

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

7
Lưu ý rằng đối với các URL đã thoát như thế http://example.com/dir/hello%20world.txtnày sẽ quay lại hello%20world.txttrong khi Uri.LocalPathcách tiếp cận sẽ trở lạihello world.txt
Jeff Moser

22

Tôi nghĩ rằng điều này sẽ làm những gì bạn cần:

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

2
Đây thực sự trông giống như một giải pháp tao nhã, nhưng hãy nhớ rằng nó chỉ hoạt động trên các URI tuyệt đối và trả về giá trị được mã hóa / thoát (sử dụng Uri.UnescapeDataString()để thay đổi% 20 và + thành dấu cách).
Ronald

8
using System.IO;

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

Tất nhiên, giả định rằng bạn đã phân tích tên tệp.

EDIT # 2:

using System.IO;

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

Điều này sẽ xử lý khoảng trắng và tương tự trong tên tệp.


3
Colons không được chấp nhận trong các đường dẫn trên tất cả các nền tảng, vì vậy loại hack này có thể thất bại, giả sử, Mono.NET chạy trên biến thể * nix. Tốt hơn nên sử dụng System.Uri vì nó được thiết kế đặc biệt để làm những gì OP cần.
richardtallent

1
Một điểm hợp lệ! Tôi luôn quên về Mono. Tôi nghĩ về không gian và những thứ tương tự, nhưng không phải là dấu hai chấm.
Mike Hofer

2

đây là mẫu của tôi bạn có thể sử dụng:

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

Sử dụng:

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

0

Đơn giản và thẳng tiến:

            Uri uri = new Uri(documentAttachment.DocumentAttachment.PreSignedUrl);
            fileName = Path.GetFileName(uri.LocalPath);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.